Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl
index 97618be..028a844 100644
--- a/Documentation/DocBook/kgdb.tmpl
+++ b/Documentation/DocBook/kgdb.tmpl
@@ -72,7 +72,7 @@
     kgdb is a source level debugger for linux kernel. It is used along
     with gdb to debug a linux kernel.  The expectation is that gdb can
     be used to "break in" to the kernel to inspect memory, variables
-    and look through a cal stack information similar to what an
+    and look through call stack information similar to what an
     application developer would use gdb for.  It is possible to place
     breakpoints in kernel code and perform some limited execution
     stepping.
@@ -93,8 +93,10 @@
   <chapter id="CompilingAKernel">
     <title>Compiling a kernel</title>
     <para>
-    To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
-    and then select "KGDB: kernel debugging with remote gdb".
+    To enable <symbol>CONFIG_KGDB</symbol> you should first turn on
+    "Prompt for development and/or incomplete code/drivers"
+    (CONFIG_EXPERIMENTAL) in  "General setup", then under the
+    "Kernel debugging" select "KGDB: kernel debugging with remote gdb".
     </para>
     <para>
     Next you should choose one of more I/O drivers to interconnect debugging
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt
index c298a66..824fc02 100644
--- a/Documentation/cgroups.txt
+++ b/Documentation/cgroups.txt
@@ -310,8 +310,8 @@
   cd /dev/cgroup
   mkdir Charlie
   cd Charlie
-  /bin/echo 2-3 > cpus
-  /bin/echo 1 > mems
+  /bin/echo 2-3 > cpuset.cpus
+  /bin/echo 1 > cpuset.mems
   /bin/echo $$ > tasks
   sh
   # The subshell 'sh' is now running in cgroup Charlie
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 3c35d45..5b3f31f 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -289,6 +289,14 @@
 
 ---------------------------
 
+What:	old style serial driver for ColdFire (CONFIG_SERIAL_COLDFIRE)
+When:	2.6.28
+Why:	This driver still uses the old interface and has been replaced
+	by CONFIG_SERIAL_MCF.
+Who:	Sebastian Siewior <sebastian@breakpoint.cc>
+
+---------------------------
+
 What:	/sys/o2cb symlink
 When:	January 2010
 Why:	/sys/fs/o2cb is the proper location for this information - /sys/o2cb
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index c2992bc..8b22d7d8 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -92,7 +92,6 @@
 	void (*destroy_inode)(struct inode *);
 	void (*dirty_inode) (struct inode *);
 	int (*write_inode) (struct inode *, int);
-	void (*put_inode) (struct inode *);
 	void (*drop_inode) (struct inode *);
 	void (*delete_inode) (struct inode *);
 	void (*put_super) (struct super_block *);
@@ -115,7 +114,6 @@
 destroy_inode:		no
 dirty_inode:		no				(must not sleep)
 write_inode:		no
-put_inode:		no
 drop_inode:		no				!!!inode_lock!!!
 delete_inode:		no
 put_super:		yes	yes	no
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 81e5be6..b7522c6 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -205,7 +205,6 @@
 
         void (*dirty_inode) (struct inode *);
         int (*write_inode) (struct inode *, int);
-        void (*put_inode) (struct inode *);
         void (*drop_inode) (struct inode *);
         void (*delete_inode) (struct inode *);
         void (*put_super) (struct super_block *);
@@ -246,9 +245,6 @@
 	inode to disc.  The second parameter indicates whether the write
 	should be synchronous or not, not all filesystems check this flag.
 
-  put_inode: called when the VFS inode is removed from the inode
-	cache.
-
   drop_inode: called when the last access to the inode is dropped,
 	with the inode_lock spinlock held.
 
diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473
index 22d8b19..2126de3 100644
--- a/Documentation/hwmon/adt7473
+++ b/Documentation/hwmon/adt7473
@@ -69,7 +69,8 @@
 
 The ADT7473 will scale the pwm between the lower and higher pwm speed when
 the temperature is between the two temperature boundaries.  PWM values range
-from 0 (off) to 255 (full speed).
+from 0 (off) to 255 (full speed).  Fan speed will be set to maximum when the
+temperature sensor associated with the PWM control exceeds temp#_max.
 
 Notes
 -----
diff --git a/Documentation/i2c/functionality b/Documentation/i2c/functionality
index 60cca24..42c17c1 100644
--- a/Documentation/i2c/functionality
+++ b/Documentation/i2c/functionality
@@ -51,26 +51,38 @@
                                   the transparent emulation layer)
 
 
-ALGORITHM/ADAPTER IMPLEMENTATION
---------------------------------
+ADAPTER IMPLEMENTATION
+----------------------
 
-When you write a new algorithm driver, you will have to implement a
-function callback `functionality', that gets an i2c_adapter structure
-pointer as its only parameter:
+When you write a new adapter driver, you will have to implement a
+function callback `functionality'. Typical implementations are given
+below.
 
-  struct i2c_algorithm {
-	/* Many other things of course; check <linux/i2c.h>! */
-	u32 (*functionality) (struct i2c_adapter *);
-  }
+A typical SMBus-only adapter would list all the SMBus transactions it
+supports. This example comes from the i2c-piix4 driver:
 
-A typically implementation is given below, from i2c-algo-bit.c:
-
-  static u32 bit_func(struct i2c_adapter *adap)
+  static u32 piix4_func(struct i2c_adapter *adapter)
   {
-	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-	       I2C_FUNC_PROTOCOL_MANGLING;
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+	       I2C_FUNC_SMBUS_BLOCK_DATA;
   }
 
+A typical full-I2C adapter would use the following (from the i2c-pxa
+driver):
+
+  static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
+  {
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+  }
+
+I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the
+addition of I2C block transactions) which i2c-core can emulate using
+I2C_FUNC_I2C without any help from the adapter driver. The idea is
+to let the client drivers check for the support of SMBus functions
+without having to care whether the said functions are implemented in
+hardware by the adapter, or emulated in software by i2c-core on top
+of an I2C adapter.
 
 
 CLIENT CHECKING
@@ -78,36 +90,33 @@
 
 Before a client tries to attach to an adapter, or even do tests to check
 whether one of the devices it supports is present on an adapter, it should
-check whether the needed functionality is present. There are two functions
-defined which should be used instead of calling the functionality hook
-in the algorithm structure directly:
+check whether the needed functionality is present. The typical way to do
+this is (from the lm75 driver):
 
-  /* Return the functionality mask */
-  extern u32 i2c_get_functionality (struct i2c_adapter *adap);
-
-  /* Return 1 if adapter supports everything we need, 0 if not. */
-  extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func);
-
-This is a typical way to use these functions (from the writing-clients
-document):
-  int foo_detect_client(struct i2c_adapter *adapter, int address, 
-                          unsigned short flags, int kind)
+  static int lm75_detect(...)
   {
-	/* Define needed variables */
-
-	/* As the very first action, we check whether the adapter has the
-	   needed functionality: we need the SMBus read_word_data,
-           write_word_data and write_byte functions in this example. */
-	if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
-	                                     I2C_FUNC_SMBUS_WRITE_BYTE))
-		goto ERROR0;
-
-	/* Now we can do the real detection */
-
-	ERROR0:
-		/* Return an error */
+	(...)
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_WORD_DATA))
+		goto exit;
+	(...)
   }
 
+Here, the lm75 driver checks if the adapter can do both SMBus byte data
+and SMBus word data transactions. If not, then the driver won't work on
+this adapter and there's no point in going on. If the check above is
+successful, then the driver knows that it can call the following
+functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(),
+i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of
+thumb, the functionality constants you test for with
+i2c_check_functionality() should match exactly the i2c_smbus_* functions
+which you driver is calling.
+
+Note that the check above doesn't tell whether the functionalities are
+implemented in hardware by the underlying adapter or emulated in
+software by i2c-core. Client drivers don't have to care about this, as
+i2c-core will transparently implement SMBus transactions on top of I2C
+adapters.
 
 
 CHECKING THROUGH /DEV
@@ -116,19 +125,19 @@
 If you try to access an adapter from a userspace program, you will have
 to use the /dev interface. You will still have to check whether the
 functionality you need is supported, of course. This is done using
-the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2cdetect
-program, is below:
+the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is
+below:
 
   int file;
-  if (file = open("/dev/i2c-0",O_RDWR) < 0) {
+  if (file = open("/dev/i2c-0", O_RDWR) < 0) {
 	/* Some kind of error handling */
 	exit(1);
   }
-  if (ioctl(file,I2C_FUNCS,&funcs) < 0) {
+  if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
 	/* Some kind of error handling */
 	exit(1);
   }
-  if (! (funcs & I2C_FUNC_SMBUS_QUICK)) {
+  if (!(funcs & I2C_FUNC_SMBUS_QUICK)) {
 	/* Oops, the needed functionality (SMBus write_quick function) is
            not available! */
 	exit(1);
diff --git a/Documentation/i2c/smbus-protocol b/Documentation/i2c/smbus-protocol
index 8a653c6..03f08fb 100644
--- a/Documentation/i2c/smbus-protocol
+++ b/Documentation/i2c/smbus-protocol
@@ -1,5 +1,6 @@
 SMBus Protocol Summary
 ======================
+
 The following is a summary of the SMBus protocol. It applies to
 all revisions of the protocol (1.0, 1.1, and 2.0).
 Certain protocol features which are not supported by
@@ -8,6 +9,7 @@
 Some adapters understand only the SMBus (System Management Bus) protocol,
 which is a subset from the I2C protocol. Fortunately, many devices use
 only the same subset, which makes it possible to put them on an SMBus.
+
 If you write a driver for some I2C device, please try to use the SMBus
 commands if at all possible (if the device uses only that subset of the
 I2C protocol). This makes it possible to use the device driver on both
@@ -15,7 +17,12 @@
 translated to I2C on I2C adapters, but plain I2C commands can not be
 handled at all on most pure SMBus adapters).
 
-Below is a list of SMBus commands.
+Below is a list of SMBus protocol operations, and the functions executing
+them.  Note that the names used in the SMBus protocol specifications usually
+don't match these function names.  For some of the operations which pass a
+single data byte, the functions using SMBus protocol operation names execute
+a different protocol operation entirely.
+
 
 Key to symbols
 ==============
@@ -35,17 +42,16 @@
 [..]: Data sent by I2C device, as opposed to data sent by the host adapter.
 
 
-SMBus Write Quick
-=================
+SMBus Quick Command:  i2c_smbus_write_quick()
+=============================================
 
 This sends a single bit to the device, at the place of the Rd/Wr bit.
-There is no equivalent Read Quick command.
 
 A Addr Rd/Wr [A] P
 
 
-SMBus Read Byte
-===============
+SMBus Receive Byte:  i2c_smbus_read_byte()
+==========================================
 
 This reads a single byte from a device, without specifying a device
 register. Some devices are so simple that this interface is enough; for
@@ -55,17 +61,17 @@
 S Addr Rd [A] [Data] NA P
 
 
-SMBus Write Byte
-================
+SMBus Send Byte:  i2c_smbus_write_byte()
+========================================
 
-This is the reverse of Read Byte: it sends a single byte to a device.
-See Read Byte for more information.
+This operation is the reverse of Receive Byte: it sends a single byte
+to a device.  See Receive Byte for more information.
 
 S Addr Wr [A] Data [A] P
 
 
-SMBus Read Byte Data
-====================
+SMBus Read Byte:  i2c_smbus_read_byte_data()
+============================================
 
 This reads a single byte from a device, from a designated register.
 The register is specified through the Comm byte.
@@ -73,30 +79,30 @@
 S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
 
 
-SMBus Read Word Data
-====================
+SMBus Read Word:  i2c_smbus_read_word_data()
+============================================
 
-This command is very like Read Byte Data; again, data is read from a
+This operation is very like Read Byte; again, data is read from a
 device, from a designated register that is specified through the Comm
 byte. But this time, the data is a complete word (16 bits).
 
 S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
 
 
-SMBus Write Byte Data
-=====================
+SMBus Write Byte:  i2c_smbus_write_byte_data()
+==============================================
 
 This writes a single byte to a device, to a designated register. The
 register is specified through the Comm byte. This is the opposite of
-the Read Byte Data command.
+the Read Byte operation.
 
 S Addr Wr [A] Comm [A] Data [A] P
 
 
-SMBus Write Word Data
-=====================
+SMBus Write Word:  i2c_smbus_write_word_data()
+==============================================
 
-This is the opposite operation of the Read Word Data command. 16 bits
+This is the opposite of the Read Word operation. 16 bits
 of data is written to a device, to the designated register that is
 specified through the Comm byte. 
 
@@ -113,8 +119,8 @@
                              S Addr Rd [A] [DataLow] A [DataHigh] NA P
 
 
-SMBus Block Read
-================
+SMBus Block Read:  i2c_smbus_read_block_data()
+==============================================
 
 This command reads a block of up to 32 bytes from a device, from a 
 designated register that is specified through the Comm byte. The amount
@@ -124,8 +130,8 @@
            S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
 
 
-SMBus Block Write
-=================
+SMBus Block Write:  i2c_smbus_write_block_data()
+================================================
 
 The opposite of the Block Read command, this writes up to 32 bytes to 
 a device, to a designated register that is specified through the
@@ -134,10 +140,11 @@
 S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
 
 
-SMBus Block Process Call
-========================
+SMBus Block Write - Block Read Process Call
+===========================================
 
-SMBus Block Process Call was introduced in Revision 2.0 of the specification.
+SMBus Block Write - Block Read Process Call was introduced in
+Revision 2.0 of the specification.
 
 This command selects a device register (through the Comm byte), sends
 1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return.
@@ -159,13 +166,16 @@
 
 Packet Error Checking (PEC)
 ===========================
+
 Packet Error Checking was introduced in Revision 1.1 of the specification.
 
-PEC adds a CRC-8 error-checking byte to all transfers.
+PEC adds a CRC-8 error-checking byte to transfers using it, immediately
+before the terminating STOP.
 
 
 Address Resolution Protocol (ARP)
 =================================
+
 The Address Resolution Protocol was introduced in Revision 2.0 of
 the specification. It is a higher-layer protocol which uses the
 messages above.
@@ -177,14 +187,17 @@
 
 I2C Block Transactions
 ======================
+
 The following I2C block transactions are supported by the
 SMBus layer and are described here for completeness.
+They are *NOT* defined by the SMBus specification.
+
 I2C block transactions do not limit the number of bytes transferred
 but the SMBus layer places a limit of 32 bytes.
 
 
-I2C Block Read
-==============
+I2C Block Read:  i2c_smbus_read_i2c_block_data()
+================================================
 
 This command reads a block of bytes from a device, from a 
 designated register that is specified through the Comm byte.
@@ -203,8 +216,8 @@
            S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
 
 
-I2C Block Write
-===============
+I2C Block Write:  i2c_smbus_write_i2c_block_data()
+==================================================
 
 The opposite of the Block Read command, this writes bytes to 
 a device, to a designated register that is specified through the
@@ -212,5 +225,3 @@
 supported as they are indistinguishable from data.
 
 S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
-
-
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a3c3544..cdd5b93 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1094,9 +1094,6 @@
 	mac5380=	[HW,SCSI] Format:
 			<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
 
-	mac53c9x=	[HW,SCSI] Format:
-			<num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
-
 	machvec=	[IA64] Force the use of a particular machine-vector
 			(machvec) in a generic kernel.
 			Example: machvec=hpzx1_swiotlb
@@ -1525,6 +1522,8 @@
 				This is normally done in pci_enable_device(),
 				so this option is a temporary workaround
 				for broken drivers that don't call it.
+		skip_isa_align	[X86] do not align io start addr, so can
+				handle more pci cards
 		firmware	[ARM] Do not re-enumerate the bus but instead
 				just use the configuration from the
 				bootloader. This is currently used on
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index e5a819a..f5b7127 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -994,7 +994,17 @@
 	DATA DEPENDENCY	read_barrier_depends()	smp_read_barrier_depends()
 
 
-All CPU memory barriers unconditionally imply compiler barriers.
+All memory barriers except the data dependency barriers imply a compiler
+barrier. Data dependencies do not impose any additional compiler ordering.
+
+Aside: In the case of data dependencies, the compiler would be expected to
+issue the loads in the correct order (eg. `a[b]` would have to load the value
+of b before loading a[b]), however there is no guarantee in the C specification
+that the compiler may not speculate the value of b (eg. is equal to 1) and load
+a before b (eg. tmp = a[1]; if (b != 1) tmp = a[b]; ). There is also the
+problem of a compiler reloading b after having loaded a[b], thus having a newer
+copy of b than a[b]. A consensus has not yet been reached about these problems,
+however the ACCESS_ONCE macro is a good place to start looking.
 
 SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
 systems because it is assumed that a CPU will appear to be self-consistent,
diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO
index 8fbc0a8..bf0baa1 100644
--- a/Documentation/s390/CommonIO
+++ b/Documentation/s390/CommonIO
@@ -8,17 +8,6 @@
 
   Enable logging of debug information in case of ccw device timeouts.
 
-
-* cio_msg = yes | no
-  
-  Determines whether information on found devices and sensed device 
-  characteristics should be shown during startup or when new devices are
-  found, i. e. messages of the types "Detected device 0.0.4711 on subchannel
-  0.0.0042" and "SenseID: Device 0.0.4711 reports: ...".
-
-  Default is off.
-
-
 * cio_ignore = {all} |
 	       {<device> | <range of devices>} |
 	       {!<device> | !<range of devices>}
diff --git a/Documentation/scheduler/sched-design.txt b/Documentation/scheduler/sched-design.txt
deleted file mode 100644
index 1605bf0..0000000
--- a/Documentation/scheduler/sched-design.txt
+++ /dev/null
@@ -1,165 +0,0 @@
-		   Goals, Design and Implementation of the
-		      new ultra-scalable O(1) scheduler
-
-
-  This is an edited version of an email Ingo Molnar sent to
-  lkml on 4 Jan 2002.  It describes the goals, design, and
-  implementation of Ingo's new ultra-scalable O(1) scheduler.
-  Last Updated: 18 April 2002.
-
-
-Goal
-====
-
-The main goal of the new scheduler is to keep all the good things we know
-and love about the current Linux scheduler:
-
- - good interactive performance even during high load: if the user
-   types or clicks then the system must react instantly and must execute
-   the user tasks smoothly, even during considerable background load.
-
- - good scheduling/wakeup performance with 1-2 runnable processes.
-
- - fairness: no process should stay without any timeslice for any
-   unreasonable amount of time. No process should get an unjustly high
-   amount of CPU time.
-
- - priorities: less important tasks can be started with lower priority,
-   more important tasks with higher priority.
-
- - SMP efficiency: no CPU should stay idle if there is work to do.
-
- - SMP affinity: processes which run on one CPU should stay affine to
-   that CPU. Processes should not bounce between CPUs too frequently.
-
- - plus additional scheduler features: RT scheduling, CPU binding.
-
-and the goal is also to add a few new things:
-
- - fully O(1) scheduling. Are you tired of the recalculation loop
-   blowing the L1 cache away every now and then? Do you think the goodness
-   loop is taking a bit too long to finish if there are lots of runnable
-   processes? This new scheduler takes no prisoners: wakeup(), schedule(),
-   the timer interrupt are all O(1) algorithms. There is no recalculation
-   loop. There is no goodness loop either.
-
- - 'perfect' SMP scalability. With the new scheduler there is no 'big'
-   runqueue_lock anymore - it's all per-CPU runqueues and locks - two
-   tasks on two separate CPUs can wake up, schedule and context-switch
-   completely in parallel, without any interlocking. All
-   scheduling-relevant data is structured for maximum scalability.
-
- - better SMP affinity. The old scheduler has a particular weakness that
-   causes the random bouncing of tasks between CPUs if/when higher
-   priority/interactive tasks, this was observed and reported by many
-   people. The reason is that the timeslice recalculation loop first needs
-   every currently running task to consume its timeslice. But when this
-   happens on eg. an 8-way system, then this property starves an
-   increasing number of CPUs from executing any process. Once the last
-   task that has a timeslice left has finished using up that timeslice,
-   the recalculation loop is triggered and other CPUs can start executing
-   tasks again - after having idled around for a number of timer ticks.
-   The more CPUs, the worse this effect.
-
-   Furthermore, this same effect causes the bouncing effect as well:
-   whenever there is such a 'timeslice squeeze' of the global runqueue,
-   idle processors start executing tasks which are not affine to that CPU.
-   (because the affine tasks have finished off their timeslices already.)
-
-   The new scheduler solves this problem by distributing timeslices on a
-   per-CPU basis, without having any global synchronization or
-   recalculation.
-
- - batch scheduling. A significant proportion of computing-intensive tasks
-   benefit from batch-scheduling, where timeslices are long and processes
-   are roundrobin scheduled. The new scheduler does such batch-scheduling
-   of the lowest priority tasks - so nice +19 jobs will get
-   'batch-scheduled' automatically. With this scheduler, nice +19 jobs are
-   in essence SCHED_IDLE, from an interactiveness point of view.
-
- - handle extreme loads more smoothly, without breakdown and scheduling
-   storms.
-
- - O(1) RT scheduling. For those RT folks who are paranoid about the
-   O(nr_running) property of the goodness loop and the recalculation loop.
-
- - run fork()ed children before the parent. Andrea has pointed out the
-   advantages of this a few months ago, but patches for this feature
-   do not work with the old scheduler as well as they should,
-   because idle processes often steal the new child before the fork()ing
-   CPU gets to execute it.
-
-
-Design
-======
-
-The core of the new scheduler contains the following mechanisms:
-
- - *two* priority-ordered 'priority arrays' per CPU. There is an 'active'
-   array and an 'expired' array. The active array contains all tasks that
-   are affine to this CPU and have timeslices left. The expired array
-   contains all tasks which have used up their timeslices - but this array
-   is kept sorted as well. The active and expired array is not accessed
-   directly, it's accessed through two pointers in the per-CPU runqueue
-   structure. If all active tasks are used up then we 'switch' the two
-   pointers and from now on the ready-to-go (former-) expired array is the
-   active array - and the empty active array serves as the new collector
-   for expired tasks.
-
- - there is a 64-bit bitmap cache for array indices. Finding the highest
-   priority task is thus a matter of two x86 BSFL bit-search instructions.
-
-the split-array solution enables us to have an arbitrary number of active
-and expired tasks, and the recalculation of timeslices can be done
-immediately when the timeslice expires. Because the arrays are always
-access through the pointers in the runqueue, switching the two arrays can
-be done very quickly.
-
-this is a hybride priority-list approach coupled with roundrobin
-scheduling and the array-switch method of distributing timeslices.
-
- - there is a per-task 'load estimator'.
-
-one of the toughest things to get right is good interactive feel during
-heavy system load. While playing with various scheduler variants i found
-that the best interactive feel is achieved not by 'boosting' interactive
-tasks, but by 'punishing' tasks that want to use more CPU time than there
-is available. This method is also much easier to do in an O(1) fashion.
-
-to establish the actual 'load' the task contributes to the system, a
-complex-looking but pretty accurate method is used: there is a 4-entry
-'history' ringbuffer of the task's activities during the last 4 seconds.
-This ringbuffer is operated without much overhead. The entries tell the
-scheduler a pretty accurate load-history of the task: has it used up more
-CPU time or less during the past N seconds. [the size '4' and the interval
-of 4x 1 seconds was found by lots of experimentation - this part is
-flexible and can be changed in both directions.]
-
-the penalty a task gets for generating more load than the CPU can handle
-is a priority decrease - there is a maximum amount to this penalty
-relative to their static priority, so even fully CPU-bound tasks will
-observe each other's priorities, and will share the CPU accordingly.
-
-the SMP load-balancer can be extended/switched with additional parallel
-computing and cache hierarchy concepts: NUMA scheduling, multi-core CPUs
-can be supported easily by changing the load-balancer. Right now it's
-tuned for my SMP systems.
-
-i skipped the prev->mm == next->mm advantage - no workload i know of shows
-any sensitivity to this. It can be added back by sacrificing O(1)
-schedule() [the current and one-lower priority list can be searched for a
-that->mm == current->mm condition], but costs a fair number of cycles
-during a number of important workloads, so i wanted to avoid this as much
-as possible.
-
-- the SMP idle-task startup code was still racy and the new scheduler
-triggered this. So i streamlined the idle-setup code a bit. We do not call
-into schedule() before all processors have started up fully and all idle
-threads are in place.
-
-- the patch also cleans up a number of aspects of sched.c - moves code
-into other areas of the kernel where it's appropriate, and simplifies
-certain code paths and data constructs. As a result, the new scheduler's
-code is smaller than the old one.
-
-	Ingo
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 929b90c..191194e 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -5,6 +5,6 @@
   4 -> DViCO FusionHDTV5 Express                           [18ac:d500]
   5 -> Hauppauge WinTV-HVR1500Q                            [0070:7790,0070:7797]
   6 -> Hauppauge WinTV-HVR1500                             [0070:7710,0070:7717]
-  7 -> Hauppauge WinTV-HVR1200                             [0070:71d1]
+  7 -> Hauppauge WinTV-HVR1200                             [0070:71d1,0070:71d3]
   8 -> Hauppauge WinTV-HVR1700                             [0070:8101]
   9 -> Hauppauge WinTV-HVR1400                             [0070:8010]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index f40e092..1d6a245 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -14,4 +14,4 @@
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
  14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
  15 -> V-Gear PocketTV                          (em2800)
- 16 -> Hauppauge WinTV HVR 950                  (em2880)        [2040:6513]
+ 16 -> Hauppauge WinTV HVR 950                  (em2880)        [2040:6513,2040:6517,2040:651b,2040:651f]
diff --git a/MAINTAINERS b/MAINTAINERS
index abe2787..bc1c008 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -367,12 +367,12 @@
 AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
 P:	Thomas Dahlmann
 M:	thomas.dahlmann@amd.com
-L:	info-linux@geode.amd.com	(subscribers-only)
+L:	linux-geode@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
 
 AMD GEODE PROCESSOR/CHIPSET SUPPORT
 P:	Jordan Crouse
-L:	info-linux@geode.amd.com	(subscribers-only)
+L:	linux-geode@lists.infradead.org (moderated for non-subscribers)
 W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
 S:	Supported
 
@@ -1230,6 +1230,15 @@
 M:	jayakumar.alsa@gmail.com
 S:	Maintained
 
+CX18 VIDEO4LINUX DRIVER
+P:	Hans Verkuil, Andy Walls
+M:	hverkuil@xs4all.nl, awalls@radix.net
+L:	ivtv-devel@ivtvdriver.org
+L:	ivtv-users@ivtvdriver.org
+L:	video4linux-list@redhat.com
+W:	http://linuxtv.org
+S:	Maintained
+
 CYBERPRO FB DRIVER
 P:	Russell King
 M:	rmk@arm.linux.org.uk
@@ -2112,12 +2121,10 @@
 S:	Maintained
 
 INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe)
-P:	Auke Kok
-M:	auke-jan.h.kok@intel.com
-P:	Jesse Brandeburg
-M:	jesse.brandeburg@intel.com
 P:	Jeff Kirsher
 M:	jeffrey.t.kirsher@intel.com
+P:	Jesse Brandeburg
+M:	jesse.brandeburg@intel.com
 P:	Bruce Allan
 M:	bruce.w.allan@intel.com
 P:	John Ronciak
diff --git a/Makefile b/Makefile
index 4492984..3140145 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 26
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Funky Weasel is Jiggy wit it
 
 # *DOCUMENTATION*
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 728bb8f..0babb64 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -544,10 +544,10 @@
 		struct resource *fb_res = &lcdc_resources[2];
 		size_t fb_len = fb_res->end - fb_res->start + 1;
 
-		fb = ioremap_writecombine(fb_res->start, fb_len);
+		fb = ioremap(fb_res->start, fb_len);
 		if (fb) {
 			memset(fb, 0, fb_len);
-			iounmap(fb, fb_len);
+			iounmap(fb);
 		}
 	}
 	lcdc_data = *data;
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 0546898..450db30 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -332,13 +332,6 @@
 		.end	= AT91SAM9RL_ID_LCDC,
 		.flags	= IORESOURCE_IRQ,
 	},
-#if defined(CONFIG_FB_INTSRAM)
-	[2] = {
-		.start	= AT91SAM9RL_SRAM_BASE,
-		.end	= AT91SAM9RL_SRAM_BASE + AT91SAM9RL_SRAM_SIZE - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-#endif
 };
 
 static struct platform_device at91_lcdc_device = {
@@ -381,20 +374,6 @@
 	at91_set_B_periph(AT91_PIN_PC24, 0);	/* LCDD22 */
 	at91_set_B_periph(AT91_PIN_PC25, 0);	/* LCDD23 */
 
-#ifdef CONFIG_FB_INTSRAM
-	{
-		void __iomem *fb;
-		struct resource *fb_res = &lcdc_resources[2];
-		size_t fb_len = fb_res->end - fb_res->start + 1;
-
-		fb = ioremap_writecombine(fb_res->start, fb_len);
-		if (fb) {
-			memset(fb, 0, fb_len);
-			iounmap(fb, fb_len);
-		}
-	}
-#endif
-
 	lcdc_data = *data;
 	platform_device_register(&at91_lcdc_device);
 }
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 8bc1872..1d7bca6 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -280,7 +280,7 @@
 	const int port = gpio >> 3;
 	const int port_mask = 1 << (gpio & 7);
 
-	gpio_direction_output(gpio, gpio_get_value(gpio));
+	gpio_direction_input(gpio);
 
 	switch (type) {
 	case IRQT_RISING:
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 36e5835..ca85d24 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -62,7 +62,7 @@
 #if 0
 #define handle_irq handle_level_irq
 #else
-void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
+static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int cpu = smp_processor_id();
 	struct irqaction *action;
@@ -70,27 +70,35 @@
 
 	spin_lock(&desc->lock);
 
-	if (unlikely(desc->status & IRQ_INPROGRESS))
-		goto out_unlock;
+	BUG_ON(desc->status & IRQ_INPROGRESS);
 
 	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
 	kstat_cpu(cpu).irqs[irq]++;
 
 	action = desc->action;
 	if (unlikely(!action || (desc->status & IRQ_DISABLED)))
-		goto out_unlock;
+		goto out_mask;
 
 	desc->status |= IRQ_INPROGRESS;
 	spin_unlock(&desc->lock);
 
 	action_ret = handle_IRQ_event(irq, action);
 
+	/* XXX: There is no direct way to access noirqdebug, so check
+	 * unconditionally for spurious irqs...
+	 * Maybe this function should go to kernel/irq/chip.c? */
+	note_interrupt(irq, desc, action_ret);
+
 	spin_lock(&desc->lock);
 	desc->status &= ~IRQ_INPROGRESS;
-	if (!(desc->status & IRQ_DISABLED) && desc->chip->ack)
-		desc->chip->ack(irq);
 
-out_unlock:
+	if (desc->status & IRQ_DISABLED)
+out_mask:
+		desc->chip->mask(irq);
+
+	/* ack unconditionally to unmask lower prio irqs */
+	desc->chip->ack(irq);
+
 	spin_unlock(&desc->lock);
 }
 #define handle_irq handle_prio_irq
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index 9608503..e63fb05 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -34,11 +34,7 @@
  * Non-CPU Masters address decoding --
  * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
  * banks only (the typical use case).
- * Setup access for each master to DDR is issued by common.c.
- *
- * Note: although orion_setbits() and orion_clrbits() are not atomic
- * no locking is necessary here since code in this file is only called
- * at boot time when there is no concurrency issues.
+ * Setup access for each master to DDR is issued by platform device setup.
  */
 
 /*
@@ -48,10 +44,6 @@
 #define TARGET_DEV_BUS		1
 #define TARGET_PCI		3
 #define TARGET_PCIE		4
-#define ATTR_DDR_CS(n)		(((n) ==0) ? 0xe :	\
-				((n) == 1) ? 0xd :	\
-				((n) == 2) ? 0xb :	\
-				((n) == 3) ? 0x7 : 0xf)
 #define ATTR_PCIE_MEM		0x59
 #define ATTR_PCIE_IO		0x51
 #define ATTR_PCIE_WA		0x79
@@ -61,17 +53,12 @@
 #define ATTR_DEV_CS1		0x1d
 #define ATTR_DEV_CS2		0x1b
 #define ATTR_DEV_BOOT		0xf
-#define WIN_EN			1
 
 /*
  * Helpers to get DDR bank info
  */
-#define DDR_BASE_CS(n)		ORION5X_DDR_REG(0x1500 + ((n) * 8))
-#define DDR_SIZE_CS(n)		ORION5X_DDR_REG(0x1504 + ((n) * 8))
-#define DDR_MAX_CS		4
-#define DDR_REG_TO_SIZE(reg)	(((reg) | 0xffffff) + 1)
-#define DDR_REG_TO_BASE(reg)	((reg) & 0xff000000)
-#define DDR_BANK_EN		1
+#define DDR_BASE_CS(n)		ORION5X_DDR_REG(0x1500 + ((n) << 3))
+#define DDR_SIZE_CS(n)		ORION5X_DDR_REG(0x1504 + ((n) << 3))
 
 /*
  * CPU Address Decode Windows registers
@@ -81,17 +68,6 @@
 #define CPU_WIN_REMAP_LO(n)	ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
 #define CPU_WIN_REMAP_HI(n)	ORION5X_BRIDGE_REG(0x00c | ((n) << 4))
 
-/*
- * Gigabit Ethernet Address Decode Windows registers
- */
-#define ETH_WIN_BASE(win)	ORION5X_ETH_REG(0x200 + ((win) * 8))
-#define ETH_WIN_SIZE(win)	ORION5X_ETH_REG(0x204 + ((win) * 8))
-#define ETH_WIN_REMAP(win)	ORION5X_ETH_REG(0x280 + ((win) * 4))
-#define ETH_WIN_EN		ORION5X_ETH_REG(0x290)
-#define ETH_WIN_PROT		ORION5X_ETH_REG(0x294)
-#define ETH_MAX_WIN		6
-#define ETH_MAX_REMAP_WIN	4
-
 
 struct mbus_dram_target_info orion5x_mbus_dram_info;
 
@@ -202,39 +178,3 @@
 {
 	setup_cpu_win(7, base, size, TARGET_PCIE, ATTR_PCIE_WA, -1);
 }
-
-void __init orion5x_setup_eth_wins(void)
-{
-	int i;
-
-	/*
-	 * First, disable and clear windows
-	 */
-	for (i = 0; i < ETH_MAX_WIN; i++) {
-		orion5x_write(ETH_WIN_BASE(i), 0);
-		orion5x_write(ETH_WIN_SIZE(i), 0);
-		orion5x_setbits(ETH_WIN_EN, 1 << i);
-		orion5x_clrbits(ETH_WIN_PROT, 0x3 << (i * 2));
-		if (i < ETH_MAX_REMAP_WIN)
-			orion5x_write(ETH_WIN_REMAP(i), 0);
-	}
-
-	/*
-	 * Setup windows for DDR banks.
-	 */
-	for (i = 0; i < DDR_MAX_CS; i++) {
-		u32 base, size;
-		size = orion5x_read(DDR_SIZE_CS(i));
-		base = orion5x_read(DDR_BASE_CS(i));
-		if (size & DDR_BANK_EN) {
-			base = DDR_REG_TO_BASE(base);
-			size = DDR_REG_TO_SIZE(size);
-			orion5x_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000);
-			orion5x_write(ETH_WIN_BASE(i), (base & 0xffff0000) |
-					(ATTR_DDR_CS(i) << 8) |
-					TARGET_DDR);
-			orion5x_clrbits(ETH_WIN_EN, 1 << i);
-			orion5x_setbits(ETH_WIN_PROT, 0x3 << (i * 2));
-		}
-	}
-}
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 968deb5..4f13fd0 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -190,6 +190,11 @@
  * (The Orion and Discovery (MV643xx) families use the same Ethernet driver)
  ****************************************************************************/
 
+struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
+	.dram		= &orion5x_mbus_dram_info,
+	.t_clk		= ORION5X_TCLK,
+};
+
 static struct resource orion5x_eth_shared_resources[] = {
 	{
 		.start	= ORION5X_ETH_PHYS_BASE + 0x2000,
@@ -201,6 +206,9 @@
 static struct platform_device orion5x_eth_shared = {
 	.name		= MV643XX_ETH_SHARED_NAME,
 	.id		= 0,
+	.dev		= {
+		.platform_data	= &orion5x_eth_shared_data,
+	},
 	.num_resources	= 1,
 	.resource	= orion5x_eth_shared_resources,
 };
@@ -223,7 +231,9 @@
 
 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
 {
+	eth_data->shared = &orion5x_eth_shared;
 	orion5x_eth.dev.platform_data = eth_data;
+
 	platform_device_register(&orion5x_eth_shared);
 	platform_device_register(&orion5x_eth);
 }
@@ -360,7 +370,6 @@
 	 * Setup Orion address map
 	 */
 	orion5x_setup_cpu_mbus_bridge();
-	orion5x_setup_eth_wins();
 
 	/*
 	 * Register devices.
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index 14adf8d..bd0f05d 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -22,7 +22,6 @@
 void orion5x_setup_dev1_win(u32 base, u32 size);
 void orion5x_setup_dev2_win(u32 base, u32 size);
 void orion5x_setup_pcie_wa_win(u32 base, u32 size);
-void orion5x_setup_eth_wins(void);
 
 /*
  * Shared code used internally by other Orion core functions.
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 6a83085..0e6d05b 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -5,6 +5,13 @@
 # Common support (must be linked before board specific support)
 obj-y				+= clock.o devices.o generic.o irq.o dma.o \
 				   time.o gpio.o
+obj-$(CONFIG_PM)		+= pm.o sleep.o standby.o
+obj-$(CONFIG_CPU_FREQ)		+= cpu-pxa.o
+
+# Generic drivers that other drivers may depend upon
+obj-$(CONFIG_PXA_SSP)		+= ssp.o
+
+# SoC-specific code
 obj-$(CONFIG_PXA25x)		+= mfp-pxa2xx.o pxa25x.o
 obj-$(CONFIG_PXA27x)		+= mfp-pxa2xx.o pxa27x.o
 obj-$(CONFIG_PXA3xx)		+= mfp-pxa3xx.o pxa3xx.o smemc.o
@@ -48,11 +55,6 @@
 
 obj-$(CONFIG_LEDS)		+= $(led-y)
 
-# Misc features
-obj-$(CONFIG_PM)		+= pm.o sleep.o standby.o
-obj-$(CONFIG_CPU_FREQ)		+= cpu-pxa.o
-obj-$(CONFIG_PXA_SSP)		+= ssp.o
-
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
 endif
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 259ca82..b757dd7 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -493,8 +493,6 @@
 
 static void corgi_poweroff(void)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	if (!machine_is_corgi())
 		/* Green LED off tells the bootloader to halt */
 		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
@@ -503,8 +501,6 @@
 
 static void corgi_restart(char mode)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	if (!machine_is_corgi())
 		/* Green LED on tells the bootloader to reboot */
 		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c
index 4b21479..fb9ba1a 100644
--- a/arch/arm/mach-pxa/cpu-pxa.c
+++ b/arch/arm/mach-pxa/cpu-pxa.c
@@ -49,125 +49,216 @@
 #define freq_debug  0
 #endif
 
+static unsigned int pxa27x_maxfreq;
+module_param(pxa27x_maxfreq, uint, 0);
+MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
+		 "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)");
+
 typedef struct {
 	unsigned int khz;
 	unsigned int membus;
 	unsigned int cccr;
 	unsigned int div2;
+	unsigned int cclkcfg;
 } pxa_freqs_t;
 
 /* Define the refresh period in mSec for the SDRAM and the number of rows */
-#define SDRAM_TREF          64      /* standard 64ms SDRAM */
-#define SDRAM_ROWS          4096    /* 64MB=8192 32MB=4096 */
-#define MDREFR_DRI(x)       (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
+#define SDRAM_TREF	64	/* standard 64ms SDRAM */
+#define SDRAM_ROWS	4096	/* 64MB=8192 32MB=4096 */
 
-#define CCLKCFG_TURBO       0x1
-#define CCLKCFG_FCS         0x2
-#define PXA25x_MIN_FREQ     99500
-#define PXA25x_MAX_FREQ     398100
-#define MDREFR_DB2_MASK     (MDREFR_K2DB2 | MDREFR_K1DB2)
-#define MDREFR_DRI_MASK     0xFFF
+#define CCLKCFG_TURBO		0x1
+#define CCLKCFG_FCS		0x2
+#define CCLKCFG_HALFTURBO	0x4
+#define CCLKCFG_FASTBUS		0x8
+#define MDREFR_DB2_MASK		(MDREFR_K2DB2 | MDREFR_K1DB2)
+#define MDREFR_DRI_MASK		0xFFF
 
-
+/*
+ * PXA255 definitions
+ */
 /* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
+#define CCLKCFG			CCLKCFG_TURBO | CCLKCFG_FCS
+
 static pxa_freqs_t pxa255_run_freqs[] =
 {
-    /* CPU   MEMBUS  CCCR  DIV2*/
-    { 99500,  99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50,  SDRAM=50 */
-    {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66,  SDRAM=66 */
-    {199100,  99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99,  SDRAM=99 */
-    {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
-    {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
-    {398100,  99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
-    {0,}
+	/* CPU   MEMBUS  CCCR  DIV2 CCLKCFG	   run  turbo PXbus SDRAM */
+	{ 99500,  99500, 0x121, 1,  CCLKCFG},	/*  99,   99,   50,   50  */
+	{132700, 132700, 0x123, 1,  CCLKCFG},	/* 133,  133,   66,   66  */
+	{199100,  99500, 0x141, 0,  CCLKCFG},	/* 199,  199,   99,   99  */
+	{265400, 132700, 0x143, 1,  CCLKCFG},	/* 265,  265,  133,   66  */
+	{331800, 165900, 0x145, 1,  CCLKCFG},	/* 331,  331,  166,   83  */
+	{398100,  99500, 0x161, 0,  CCLKCFG},	/* 398,  398,  196,   99  */
 };
-#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
-
-static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
 
 /* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
 static pxa_freqs_t pxa255_turbo_freqs[] =
 {
-    /* CPU   MEMBUS  CCCR  DIV2*/
-    { 99500, 99500,  0x121, 1}, /* run=99,  turbo= 99, PXbus=50, SDRAM=50 */
-    {199100, 99500,  0x221, 0}, /* run=99,  turbo=199, PXbus=50, SDRAM=99 */
-    {298500, 99500,  0x321, 0}, /* run=99,  turbo=287, PXbus=50, SDRAM=99 */
-    {298600, 99500,  0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
-    {398100, 99500,  0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
-    {0,}
+	/* CPU   MEMBUS  CCCR  DIV2 CCLKCFG	   run  turbo PXbus SDRAM */
+	{ 99500, 99500,  0x121, 1,  CCLKCFG},	/*  99,   99,   50,   50  */
+	{199100, 99500,  0x221, 0,  CCLKCFG},	/*  99,  199,   50,   99  */
+	{298500, 99500,  0x321, 0,  CCLKCFG},	/*  99,  287,   50,   99  */
+	{298600, 99500,  0x1c1, 0,  CCLKCFG},	/* 199,  287,   99,   99  */
+	{398100, 99500,  0x241, 0,  CCLKCFG},	/* 199,  398,   99,   99  */
 };
-#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
 
-static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
+#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
+#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
+
+static struct cpufreq_frequency_table
+	pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1];
+static struct cpufreq_frequency_table
+	pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1];
+
+/*
+ * PXA270 definitions
+ *
+ * For the PXA27x:
+ * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG.
+ *
+ * A = 0 => memory controller clock from table 3-7,
+ * A = 1 => memory controller clock = system bus clock
+ * Run mode frequency	= 13 MHz * L
+ * Turbo mode frequency = 13 MHz * L * N
+ * System bus frequency = 13 MHz * L / (B + 1)
+ *
+ * In CCCR:
+ * A = 1
+ * L = 16	  oscillator to run mode ratio
+ * 2N = 6	  2 * (turbo mode to run mode ratio)
+ *
+ * In CCLKCFG:
+ * B = 1	  Fast bus mode
+ * HT = 0	  Half-Turbo mode
+ * T = 1	  Turbo mode
+ *
+ * For now, just support some of the combinations in table 3-7 of
+ * PXA27x Processor Family Developer's Manual to simplify frequency
+ * change sequences.
+ */
+#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L)
+#define CCLKCFG2(B, HT, T) \
+  (CCLKCFG_FCS | \
+   ((B)  ? CCLKCFG_FASTBUS : 0) | \
+   ((HT) ? CCLKCFG_HALFTURBO : 0) | \
+   ((T)  ? CCLKCFG_TURBO : 0))
+
+static pxa_freqs_t pxa27x_freqs[] = {
+	{104000, 104000, PXA27x_CCCR(1,	 8, 2), 0, CCLKCFG2(1, 0, 1)},
+	{156000, 104000, PXA27x_CCCR(1,	 8, 6), 0, CCLKCFG2(1, 1, 1)},
+	{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)},
+	{312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)},
+	{416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)},
+	{520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)},
+	{624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)}
+};
+
+#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs)
+static struct cpufreq_frequency_table
+	pxa27x_freq_table[NUM_PXA27x_FREQS+1];
 
 extern unsigned get_clk_frequency_khz(int info);
 
+static void find_freq_tables(struct cpufreq_policy *policy,
+			     struct cpufreq_frequency_table **freq_table,
+			     pxa_freqs_t **pxa_freqs)
+{
+	if (cpu_is_pxa25x()) {
+		if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
+			*pxa_freqs = pxa255_run_freqs;
+			*freq_table = pxa255_run_freq_table;
+		} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
+			*pxa_freqs = pxa255_turbo_freqs;
+			*freq_table = pxa255_turbo_freq_table;
+		} else {
+			printk("CPU PXA: Unknown policy found. "
+			       "Using CPUFREQ_POLICY_PERFORMANCE\n");
+			*pxa_freqs = pxa255_run_freqs;
+			*freq_table = pxa255_run_freq_table;
+		}
+	}
+	if (cpu_is_pxa27x()) {
+		*pxa_freqs = pxa27x_freqs;
+		*freq_table = pxa27x_freq_table;
+	}
+}
+
+static void pxa27x_guess_max_freq(void)
+{
+	if (!pxa27x_maxfreq) {
+		pxa27x_maxfreq = 416000;
+		printk(KERN_INFO "PXA CPU 27x max frequency not defined "
+		       "(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n",
+		       pxa27x_maxfreq);
+	} else {
+		pxa27x_maxfreq *= 1000;
+	}
+}
+
+static u32 mdrefr_dri(unsigned int freq)
+{
+	u32 dri = 0;
+
+	if (cpu_is_pxa25x())
+		dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS * 32));
+	if (cpu_is_pxa27x())
+		dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS - 31)) / 32;
+	return dri;
+}
+
 /* find a valid frequency point */
 static int pxa_verify_policy(struct cpufreq_policy *policy)
 {
 	struct cpufreq_frequency_table *pxa_freqs_table;
+	pxa_freqs_t *pxa_freqs;
 	int ret;
 
-	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-		pxa_freqs_table = pxa255_run_freq_table;
-	} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-		pxa_freqs_table = pxa255_turbo_freq_table;
-	} else {
-		printk("CPU PXA: Unknown policy found. "
-		       "Using CPUFREQ_POLICY_PERFORMANCE\n");
-		pxa_freqs_table = pxa255_run_freq_table;
-	}
-
+	find_freq_tables(policy, &pxa_freqs_table, &pxa_freqs);
 	ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
 
 	if (freq_debug)
 		pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
-		       policy->min, policy->max);
+			 policy->min, policy->max);
 
 	return ret;
 }
 
+static unsigned int pxa_cpufreq_get(unsigned int cpu)
+{
+	return get_clk_frequency_khz(0);
+}
+
 static int pxa_set_target(struct cpufreq_policy *policy,
-			   unsigned int target_freq,
-			   unsigned int relation)
+			  unsigned int target_freq,
+			  unsigned int relation)
 {
 	struct cpufreq_frequency_table *pxa_freqs_table;
 	pxa_freqs_t *pxa_freq_settings;
 	struct cpufreq_freqs freqs;
 	unsigned int idx;
 	unsigned long flags;
-	unsigned int unused, preset_mdrefr, postset_mdrefr;
-	void *ramstart = phys_to_virt(0xa0000000);
+	unsigned int new_freq_cpu, new_freq_mem;
+	unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
 
 	/* Get the current policy */
-	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-		pxa_freq_settings = pxa255_run_freqs;
-		pxa_freqs_table   = pxa255_run_freq_table;
-	} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-		pxa_freq_settings = pxa255_turbo_freqs;
-		pxa_freqs_table   = pxa255_turbo_freq_table;
-	} else {
-		printk("CPU PXA: Unknown policy found. "
-		       "Using CPUFREQ_POLICY_PERFORMANCE\n");
-		pxa_freq_settings = pxa255_run_freqs;
-		pxa_freqs_table   = pxa255_run_freq_table;
-	}
+	find_freq_tables(policy, &pxa_freqs_table, &pxa_freq_settings);
 
 	/* Lookup the next frequency */
 	if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
-	                                   target_freq, relation, &idx)) {
+					   target_freq, relation, &idx)) {
 		return -EINVAL;
 	}
 
+	new_freq_cpu = pxa_freq_settings[idx].khz;
+	new_freq_mem = pxa_freq_settings[idx].membus;
 	freqs.old = policy->cur;
-	freqs.new = pxa_freq_settings[idx].khz;
+	freqs.new = new_freq_cpu;
 	freqs.cpu = policy->cpu;
 
 	if (freq_debug)
-		pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
-		       freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
-		       (pxa_freq_settings[idx].membus / 2000) :
-		       (pxa_freq_settings[idx].membus / 1000));
+		pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, "
+			 "(SDRAM %d Mhz)\n",
+			 freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
+			 (new_freq_mem / 2000) : (new_freq_mem / 1000));
 
 	/*
 	 * Tell everyone what we're about to do...
@@ -177,16 +268,16 @@
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
 	/* Calculate the next MDREFR.  If we're slowing down the SDRAM clock
-	 * we need to preset the smaller DRI before the change.  If we're speeding
-	 * up we need to set the larger DRI value after the change.
+	 * we need to preset the smaller DRI before the change.	 If we're
+	 * speeding up we need to set the larger DRI value after the change.
 	 */
 	preset_mdrefr = postset_mdrefr = MDREFR;
-	if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
-		preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
-		                MDREFR_DRI(pxa_freq_settings[idx].membus);
+	if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
+		preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
+		preset_mdrefr |= mdrefr_dri(new_freq_mem);
 	}
-	postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
-		            MDREFR_DRI(pxa_freq_settings[idx].membus);
+	postset_mdrefr =
+		(postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem);
 
 	/* If we're dividing the memory clock by two for the SDRAM clock, this
 	 * must be set prior to the change.  Clearing the divide must be done
@@ -201,26 +292,27 @@
 
 	local_irq_save(flags);
 
-	/* Set new the CCCR */
+	/* Set new the CCCR and prepare CCLKCFG */
 	CCCR = pxa_freq_settings[idx].cccr;
+	cclkcfg = pxa_freq_settings[idx].cclkcfg;
 
 	asm volatile("							\n\
 		ldr	r4, [%1]		/* load MDREFR */	\n\
 		b	2f						\n\
-		.align	5 						\n\
+		.align	5						\n\
 1:									\n\
-		str	%4, [%1]		/* preset the MDREFR */	\n\
+		str	%3, [%1]		/* preset the MDREFR */	\n\
 		mcr	p14, 0, %2, c6, c0, 0	/* set CCLKCFG[FCS] */	\n\
-		str	%5, [%1]		/* postset the MDREFR */ \n\
+		str	%4, [%1]		/* postset the MDREFR */ \n\
 									\n\
 		b	3f						\n\
 2:		b	1b						\n\
 3:		nop							\n\
 	  "
-	  : "=&r" (unused)
-	  : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
-	    "r" (preset_mdrefr), "r" (postset_mdrefr)
-	  : "r4", "r5");
+		     : "=&r" (unused)
+		     : "r" (&MDREFR), "r" (cclkcfg),
+		       "r" (preset_mdrefr), "r" (postset_mdrefr)
+		     : "r4", "r5");
 	local_irq_restore(flags);
 
 	/*
@@ -233,38 +325,57 @@
 	return 0;
 }
 
-static unsigned int pxa_cpufreq_get(unsigned int cpu)
-{
-	return get_clk_frequency_khz(0);
-}
-
-static int pxa_cpufreq_init(struct cpufreq_policy *policy)
+static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
 {
 	int i;
+	unsigned int freq;
+
+	/* try to guess pxa27x cpu */
+	if (cpu_is_pxa27x())
+		pxa27x_guess_max_freq();
 
 	/* set default policy and cpuinfo */
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-	policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
-	policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
+	if (cpu_is_pxa25x())
+		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
-	policy->cur = get_clk_frequency_khz(0);    /* current freq */
+	policy->cur = get_clk_frequency_khz(0);	   /* current freq */
 	policy->min = policy->max = policy->cur;
 
-	/* Generate the run cpufreq_frequency_table struct */
-	for (i = 0; i < NUM_RUN_FREQS; i++) {
+	/* Generate pxa25x the run cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) {
 		pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
 		pxa255_run_freq_table[i].index = i;
 	}
-
 	pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
-	/* Generate the turbo cpufreq_frequency_table struct */
-	for (i = 0; i < NUM_TURBO_FREQS; i++) {
-		pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
+
+	/* Generate pxa25x the turbo cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) {
+		pxa255_turbo_freq_table[i].frequency =
+			pxa255_turbo_freqs[i].khz;
 		pxa255_turbo_freq_table[i].index = i;
 	}
 	pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
+	/* Generate the pxa27x cpufreq_frequency_table struct */
+	for (i = 0; i < NUM_PXA27x_FREQS; i++) {
+		freq = pxa27x_freqs[i].khz;
+		if (freq > pxa27x_maxfreq)
+			break;
+		pxa27x_freq_table[i].frequency = freq;
+		pxa27x_freq_table[i].index = i;
+	}
+	pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+	/*
+	 * Set the policy's minimum and maximum frequencies from the tables
+	 * just constructed.  This sets cpuinfo.mxx_freq, min and max.
+	 */
+	if (cpu_is_pxa25x())
+		cpufreq_frequency_table_cpuinfo(policy, pxa255_run_freq_table);
+	else if (cpu_is_pxa27x())
+		cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table);
+
 	printk(KERN_INFO "PXA CPU frequency change support initialized\n");
 
 	return 0;
@@ -275,26 +386,25 @@
 	.target	= pxa_set_target,
 	.init	= pxa_cpufreq_init,
 	.get	= pxa_cpufreq_get,
-	.name	= "PXA25x",
+	.name	= "PXA2xx",
 };
 
 static int __init pxa_cpu_init(void)
 {
 	int ret = -ENODEV;
-	if (cpu_is_pxa25x())
+	if (cpu_is_pxa25x() || cpu_is_pxa27x())
 		ret = cpufreq_register_driver(&pxa_cpufreq_driver);
 	return ret;
 }
 
 static void __exit pxa_cpu_exit(void)
 {
-	if (cpu_is_pxa25x())
-		cpufreq_unregister_driver(&pxa_cpufreq_driver);
+	cpufreq_unregister_driver(&pxa_cpufreq_driver);
 }
 
 
-MODULE_AUTHOR ("Intrinsyc Software Inc.");
-MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
+MODULE_AUTHOR("Intrinsyc Software Inc.");
+MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture");
 MODULE_LICENSE("GPL");
 module_init(pxa_cpu_init);
 module_exit(pxa_cpu_exit);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 0993f4d..7b9bdd0 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -396,7 +396,7 @@
 	.cmap_inverse	= 0,
 	.cmap_static	= 0,
 	.lcd_conn	= LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
-			  LCD_AC_BIAS_FREQ(255);
+			  LCD_AC_BIAS_FREQ(255),
 };
 
 #define	MMC_POLL_RATE		msecs_to_jiffies(1000)
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index ec1bbf3..7d4debb 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -42,20 +42,17 @@
 	if (state != PM_SUSPEND_STANDBY) {
 		pxa_cpu_pm_fns->save(sleep_save);
 		/* before sleeping, calculate and save a checksum */
-		for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+		for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
 			sleep_save_checksum += sleep_save[i];
 	}
 
-	/* Clear reset status */
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	/* *** go zzz *** */
 	pxa_cpu_pm_fns->enter(state);
 	cpu_init();
 
 	if (state != PM_SUSPEND_STANDBY) {
 		/* after sleeping, validate the checksum */
-		for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+		for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
 			checksum += sleep_save[i];
 
 		/* if invalid, display message and wait for a hardware reset */
@@ -101,7 +98,8 @@
 		return -EINVAL;
 	}
 
-	sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL);
+	sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long),
+			     GFP_KERNEL);
 	if (!sleep_save) {
 		printk(KERN_ERR "failed to alloc memory for pm save\n");
 		return -ENOMEM;
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index ca5ac19..0b30f25 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -326,13 +326,11 @@
 
 static void poodle_poweroff(void)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
 	arm_machine_restart('h');
 }
 
 static void poodle_restart(char mode)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
 	arm_machine_restart('h');
 }
 
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index d9b5450..e5b417d 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -150,9 +150,7 @@
  * More ones like CP and general purpose register values are preserved
  * with the stack pointer in sleep.S.
  */
-enum {	SLEEP_SAVE_START = 0,
-
-	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
+enum {	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
 
 	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
 	SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
@@ -162,7 +160,7 @@
 
 	SLEEP_SAVE_CKEN,
 
-	SLEEP_SAVE_SIZE
+	SLEEP_SAVE_COUNT
 };
 
 
@@ -200,6 +198,9 @@
 
 static void pxa25x_cpu_pm_enter(suspend_state_t state)
 {
+	/* Clear reset status */
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
 	switch (state) {
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
@@ -210,7 +211,7 @@
 }
 
 static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
-	.save_size	= SLEEP_SAVE_SIZE,
+	.save_count	= SLEEP_SAVE_COUNT,
 	.valid		= suspend_valid_only_mem,
 	.save		= pxa25x_cpu_pm_save,
 	.restore	= pxa25x_cpu_pm_restore,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 7a2449d..7e94583 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -181,9 +181,7 @@
  * More ones like CP and general purpose register values are preserved
  * with the stack pointer in sleep.S.
  */
-enum {	SLEEP_SAVE_START = 0,
-
-	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
+enum {	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
 
 	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
 	SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
@@ -198,7 +196,7 @@
 	SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
 	SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
 
-	SLEEP_SAVE_SIZE
+	SLEEP_SAVE_COUNT
 };
 
 void pxa27x_cpu_pm_save(unsigned long *sleep_save)
@@ -251,6 +249,9 @@
 	/* Clear edge-detect status register. */
 	PEDR = 0xDF12FE1B;
 
+	/* Clear reset status */
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
 	switch (state) {
 	case PM_SUSPEND_STANDBY:
 		pxa_cpu_standby();
@@ -269,7 +270,7 @@
 }
 
 static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
-	.save_size	= SLEEP_SAVE_SIZE,
+	.save_count	= SLEEP_SAVE_COUNT,
 	.save		= pxa27x_cpu_pm_save,
 	.restore	= pxa27x_cpu_pm_restore,
 	.valid		= pxa27x_cpu_pm_valid,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index b6a6f5f..644550b 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -256,12 +256,11 @@
 #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
 
-enum {	SLEEP_SAVE_START = 0,
-	SLEEP_SAVE_CKENA,
+enum {	SLEEP_SAVE_CKENA,
 	SLEEP_SAVE_CKENB,
 	SLEEP_SAVE_ACCR,
 
-	SLEEP_SAVE_SIZE,
+	SLEEP_SAVE_COUNT,
 };
 
 static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
@@ -376,7 +375,7 @@
 }
 
 static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
-	.save_size	= SLEEP_SAVE_SIZE,
+	.save_count	= SLEEP_SAVE_COUNT,
 	.save		= pxa3xx_cpu_pm_save,
 	.restore	= pxa3xx_cpu_pm_restore,
 	.valid		= pxa3xx_cpu_pm_valid,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 62a02c3..e7d0fcd 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -529,8 +529,6 @@
 
 static void spitz_poweroff(void)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
 	GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);
 
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 7a7f5f9..23f050f 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -119,9 +119,6 @@
 	/* nRESET_OUT Disable */
 	PSLR |= PSLR_SL_ROD;
 
-	/* Clear reset status */
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
 	PCFR = PCFR_GPR_EN | PCFR_OPDE;
 }
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 6458f6d..c2cbd66 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -467,8 +467,6 @@
 
 static void tosa_poweroff(void)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
 	pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT);
 	GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
 
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 246c573..1693d44 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -43,20 +43,18 @@
  * More ones like CP and general purpose register values are preserved
  * on the stack and then the stack pointer is stored last in sleep.S.
  */
-enum {	SLEEP_SAVE_SP = 0,
-
-	SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
+enum {	SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
 	SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
 
 	SLEEP_SAVE_Ser1SDCR0,
 
-	SLEEP_SAVE_SIZE
+	SLEEP_SAVE_COUNT
 };
 
 
 static int sa11x0_pm_enter(suspend_state_t state)
 {
-	unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
+	unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
 
 	gpio = GPLR;
 
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index d84167f..3ac8d8d 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -411,7 +411,7 @@
 
 	clk->parent = parent;
 
-	if (clk == &s3c24xx_dclk0)
+	if (clk == &s3c24xx_clkout0)
 		mask = S3C2410_MISCCR_CLK0_MASK;
 	else {
 		source <<= 4;
@@ -437,7 +437,7 @@
 struct clk s3c24xx_dclk1 = {
 	.name		= "dclk1",
 	.id		= -1,
-	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
+	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
 	.enable		= s3c24xx_dclk_enable,
 	.set_parent	= s3c24xx_dclk_setparent,
 	.set_rate	= s3c24xx_set_dclk_rate,
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 795d0ac..fd57085 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -832,6 +832,7 @@
 config BANK_1
 	hex "Bank 1"
 	default 0x7BB0
+	default 0x5558 if BF54x
 
 config BANK_2
 	hex "Bank 2"
@@ -963,21 +964,22 @@
 
 endmenu
 
-if (BF537 || BF533 || BF54x)
-
 menu "CPU Frequency scaling"
 
 source "drivers/cpufreq/Kconfig"
 
-config CPU_FREQ
-	bool
+config CPU_VOLTAGE
+	bool "CPU Voltage scaling"
+	depends on EXPERIMENTAL	
+	depends on CPU_FREQ
 	default n
 	help
-	  If you want to enable this option, you should select the
-	  DPMC driver from Character Devices.
-endmenu
+	  Say Y here if you want CPU voltage scaling according to the CPU frequency.
+	  This option violates the PLL BYPASS recommendation in the Blackfin Processor
+	  manuals. There is a theoretical risk that during VDDINT transitions 
+	  the PLL may unlock.
 
-endif
+endmenu
 
 source "net/Kconfig"
 
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index 721f15f..881afe9 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -56,9 +56,6 @@
 	/* offsets into the thread struct */
 	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
 	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
-	DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat));
-	DEFINE(PT_SR, offsetof(struct thread_struct, seqstat));
-	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
 	DEFINE(THREAD_PC, offsetof(struct thread_struct, pc));
 	DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
 
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
index 5ed47228..4b03ba0 100644
--- a/arch/blackfin/kernel/fixed_code.S
+++ b/arch/blackfin/kernel/fixed_code.S
@@ -1,6 +1,6 @@
 /*
  * This file contains sequences of code that will be copied to a
- * fixed location, defined in <asm/atomic_seq.h>.  The interrupt
+ * fixed location, defined in <asm/fixed_code.h>.  The interrupt
  * handlers ensure that these sequences appear to be atomic when
  * executed from userspace.
  * These are aligned to 16 bytes, so that we have some space to replace
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index 8b9fe29..14a4284 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -160,6 +160,13 @@
 module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
 			  char *secstrings, struct module *mod)
 {
+	/*
+	 * XXX: sechdrs are vmalloced in kernel/module.c
+	 * and would be vfreed just after module is loaded,
+	 * so we hack to keep the only information we needed
+	 * in mod->arch to correctly free L1 I/D sram later.
+	 * NOTE: this breaks the semantic of mod->arch structure.
+	 */
 	Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
 	void *dest = NULL;
 
@@ -167,8 +174,8 @@
 		if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
 		    ((strcmp(".text", secstrings + s->sh_name) == 0) &&
 		     (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
-			mod->arch.text_l1 = s;
 			dest = l1_inst_sram_alloc(s->sh_size);
+			mod->arch.text_l1 = dest;
 			if (dest == NULL) {
 				printk(KERN_ERR
 				       "module %s: L1 instruction memory allocation failed\n",
@@ -182,8 +189,8 @@
 		if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
 		    ((strcmp(".data", secstrings + s->sh_name) == 0) &&
 		     (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
-			mod->arch.data_a_l1 = s;
 			dest = l1_data_sram_alloc(s->sh_size);
+			mod->arch.data_a_l1 = dest;
 			if (dest == NULL) {
 				printk(KERN_ERR
 					"module %s: L1 data memory allocation failed\n",
@@ -197,8 +204,8 @@
 		if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
 		    ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
 		     (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
-			mod->arch.bss_a_l1 = s;
 			dest = l1_data_sram_alloc(s->sh_size);
+			mod->arch.bss_a_l1 = dest;
 			if (dest == NULL) {
 				printk(KERN_ERR
 					"module %s: L1 data memory allocation failed\n",
@@ -210,8 +217,8 @@
 			s->sh_addr = (unsigned long)dest;
 		}
 		if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
-			mod->arch.data_b_l1 = s;
 			dest = l1_data_B_sram_alloc(s->sh_size);
+			mod->arch.data_b_l1 = dest;
 			if (dest == NULL) {
 				printk(KERN_ERR
 					"module %s: L1 data memory allocation failed\n",
@@ -223,8 +230,8 @@
 			s->sh_addr = (unsigned long)dest;
 		}
 		if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
-			mod->arch.bss_b_l1 = s;
 			dest = l1_data_B_sram_alloc(s->sh_size);
+			mod->arch.bss_b_l1 = dest;
 			if (dest == NULL) {
 				printk(KERN_ERR
 					"module %s: L1 data memory allocation failed\n",
@@ -416,14 +423,14 @@
 
 void module_arch_cleanup(struct module *mod)
 {
-	if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
-		l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
-	if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
-		l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
-	if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
-		l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
-	if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
-		l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
-	if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
-		l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
+	if (mod->arch.text_l1)
+		l1_inst_sram_free((void *)mod->arch.text_l1);
+	if (mod->arch.data_a_l1)
+		l1_data_sram_free((void *)mod->arch.data_a_l1);
+	if (mod->arch.bss_a_l1)
+		l1_data_sram_free((void *)mod->arch.bss_a_l1);
+	if (mod->arch.data_b_l1)
+		l1_data_B_sram_free((void *)mod->arch.data_b_l1);
+	if (mod->arch.bss_b_l1)
+		l1_data_B_sram_free((void *)mod->arch.bss_b_l1);
 }
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index be9fdd0..53c2cd25 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -245,7 +245,7 @@
 
 void finish_atomic_sections (struct pt_regs *regs)
 {
-	int __user *up0 = (int __user *)&regs->p0;
+	int __user *up0 = (int __user *)regs->p0;
 
 	if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
 		return;
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index b4f062c..f51ab08 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -185,8 +185,8 @@
 {
 	unsigned long tmp;
 	/* make sure the single step bit is not set. */
-	tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
-	put_reg(child, PT_SR, tmp);
+	tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS;
+	put_reg(child, PT_SYSCFG, tmp);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index cb9d883..dbc3bbf 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -42,6 +42,9 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
+/* Location of the trace bit in SYSCFG. */
+#define TRACE_BITS 0x0001
+
 struct fdpic_func_descriptor {
 	unsigned long	text;
 	unsigned long	GOT;
@@ -225,6 +228,16 @@
 	regs->r1 = (unsigned long)(&frame->info);
 	regs->r2 = (unsigned long)(&frame->uc);
 
+	/*
+	 * Clear the trace flag when entering the signal handler, but
+	 * notify any tracer that was single-stepping it. The tracer
+	 * may want to single-step inside the handler too.
+	 */
+	if (regs->syscfg & TRACE_BITS) {
+		regs->syscfg &= ~TRACE_BITS;
+		ptrace_notify(SIGTRAP);
+	}
+
 	return 0;
 
  give_sigsegv:
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 4482c47..e887efc 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -60,7 +60,7 @@
 
 static cycle_t read_cycles(void)
 {
-	return get_cycles();
+	return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
 }
 
 unsigned long long sched_clock(void)
@@ -117,7 +117,7 @@
 		break;
 	}
 	case CLOCK_EVT_MODE_ONESHOT:
-		bfin_write_TSCALE(0);
+		bfin_write_TSCALE(TIME_SCALE - 1);
 		bfin_write_TCOUNT(0);
 		bfin_write_TCNTL(TMPWR | TMREN);
 		CSYNC();
@@ -183,10 +183,14 @@
 
 static int __init bfin_clockevent_init(void)
 {
+	unsigned long timer_clk;
+
+	timer_clk = get_cclk() / TIME_SCALE;
+
 	setup_irq(IRQ_CORETMR, &bfin_timer_irq);
 	bfin_timer_init();
 
-	clockevent_bfin.mult = div_sc(get_cclk(), NSEC_PER_SEC, clockevent_bfin.shift);
+	clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
 	clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
 	clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
 	clockevents_register_device(&clockevent_bfin);
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 583d538..8aa49f8 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -32,12 +32,14 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
 #include <linux/ata_platform.h>
+#include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/sl811.h>
@@ -50,6 +52,7 @@
 #include <asm/reboot.h>
 #include <asm/nand.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 #include <linux/spi/ad7877.h>
 
 /*
@@ -171,6 +174,46 @@
 };
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition ezkit_partitions[] = {
+	{
+		.name       = "Bootloader",
+		.size       = 0x40000,
+		.offset     = 0,
+	}, {
+		.name       = "Kernel",
+		.size       = 0x1C0000,
+		.offset     = MTDPART_OFS_APPEND,
+	}, {
+		.name       = "RootFS",
+		.size       = MTDPART_SIZ_FULL,
+		.offset     = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct physmap_flash_data ezkit_flash_data = {
+	.width      = 2,
+	.parts      = ezkit_partitions,
+	.nr_parts   = ARRAY_SIZE(ezkit_partitions),
+};
+
+static struct resource ezkit_flash_resource = {
+	.start = 0x20000000,
+	.end   = 0x203fffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ezkit_flash_device = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &ezkit_flash_data,
+	},
+	.num_resources = 1,
+	.resource      = &ezkit_flash_resource,
+};
+#endif
+
 #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
 static struct mtd_partition partition_info[] = {
 	{
@@ -420,11 +463,7 @@
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
 	}, {
-		.name = "kernel",
-		.size = 0xe0000,
-		.offset = MTDPART_OFS_APPEND,
-	}, {
-		.name = "file system",
+		.name = "linux kernel",
 		.size = MTDPART_SIZ_FULL,
 		.offset = MTDPART_OFS_APPEND,
 	}
@@ -434,7 +473,7 @@
 	.name = "m25p80",
 	.parts = bfin_spi_flash_partitions,
 	.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
-	.type = "m25p64",
+	.type = "m25p16",
 };
 
 /* SPI flash chip (m25p64) */
@@ -755,6 +794,24 @@
 };
 #endif
 
+#ifdef CONFIG_I2C_BOARDINFO
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
+	{
+		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
+		.type = "pcf8574_lcd",
+	},
+#endif
+#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+	{
+		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
+		.type = "pcf8574_keypad",
+		.irq = IRQ_PF8,
+	},
+#endif
+};
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
@@ -839,7 +896,32 @@
 	.resource = &bfin_gpios_resources,
 };
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_100, 400000000),
+	VRPAIR(VLEV_105, 426000000),
+	VRPAIR(VLEV_110, 500000000),
+	VRPAIR(VLEV_115, 533000000),
+	VRPAIR(VLEV_120, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *stamp_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
 	&bf5xx_nand_device,
 #endif
@@ -921,12 +1003,22 @@
 	&bfin_device_gpiokeys,
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+	&ezkit_flash_device,
+#endif
+
 	&bfin_gpios_device,
 };
 
 static int __init stamp_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
+
+#ifdef CONFIG_I2C_BOARDINFO
+	i2c_register_board_info(0, bfin_i2c_board_info,
+				ARRAY_SIZE(bfin_i2c_board_info));
+#endif
+
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 	spi_register_board_info(bfin_spi_board_info,
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index a03149c..ed2b0b8 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -33,12 +33,15 @@
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
+#endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -341,7 +344,37 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 376000000),
+	VRPAIR(VLEV_095, 426000000),
+	VRPAIR(VLEV_100, 426000000),
+	VRPAIR(VLEV_105, 476000000),
+	VRPAIR(VLEV_110, 476000000),
+	VRPAIR(VLEV_115, 476000000),
+	VRPAIR(VLEV_120, 600000000),
+	VRPAIR(VLEV_125, 600000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *cm_bf533_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 	&bfin_uart_device,
 #endif
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 08a7943..9d28415 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -42,6 +42,7 @@
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -350,7 +351,37 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 376000000),
+	VRPAIR(VLEV_095, 426000000),
+	VRPAIR(VLEV_100, 426000000),
+	VRPAIR(VLEV_105, 476000000),
+	VRPAIR(VLEV_110, 476000000),
+	VRPAIR(VLEV_115, 476000000),
+	VRPAIR(VLEV_120, 600000000),
+	VRPAIR(VLEV_125, 600000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *ezkit_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
 	&smc91x_device,
 #endif
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 024f418..7fd35fb 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -45,6 +45,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/reboot.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -516,7 +517,37 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 376000000),
+	VRPAIR(VLEV_095, 426000000),
+	VRPAIR(VLEV_100, 426000000),
+	VRPAIR(VLEV_105, 476000000),
+	VRPAIR(VLEV_110, 476000000),
+	VRPAIR(VLEV_115, 476000000),
+	VRPAIR(VLEV_120, 600000000),
+	VRPAIR(VLEV_125, 600000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *stamp_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 	&rtc_device,
 #endif
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
index d8a23cd..73f2142 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -35,12 +35,15 @@
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
+#endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -428,7 +431,37 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 376000000),
+	VRPAIR(VLEV_095, 426000000),
+	VRPAIR(VLEV_100, 426000000),
+	VRPAIR(VLEV_105, 476000000),
+	VRPAIR(VLEV_110, 476000000),
+	VRPAIR(VLEV_115, 476000000),
+	VRPAIR(VLEV_120, 500000000),
+	VRPAIR(VLEV_125, 533000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *cm_bf537_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
 	&hitachi_fb_device,
 #endif
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index d3727b7..9a756d1 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -47,6 +47,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/reboot.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 #include <linux/spi/ad7877.h>
 
 /*
@@ -817,7 +818,37 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 376000000),
+	VRPAIR(VLEV_095, 426000000),
+	VRPAIR(VLEV_100, 426000000),
+	VRPAIR(VLEV_105, 476000000),
+	VRPAIR(VLEV_110, 476000000),
+	VRPAIR(VLEV_115, 476000000),
+	VRPAIR(VLEV_120, 500000000),
+	VRPAIR(VLEV_125, 533000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *stamp_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
 	&bfin_pcmcia_cf_device,
 #endif
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index e3e8479..3b74f96 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -36,7 +36,9 @@
 #include <linux/spi/flash.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
 #include <linux/usb/musb.h>
+#endif
 #include <asm/bfin5xx_spi.h>
 #include <asm/cplb.h>
 #include <asm/dma.h>
@@ -44,6 +46,7 @@
 #include <asm/nand.h>
 #include <asm/portmux.h>
 #include <asm/mach/bf54x_keys.h>
+#include <asm/dpmc.h>
 #include <linux/input.h>
 #include <linux/spi/ad7877.h>
 
@@ -590,7 +593,38 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+/*
+ * Internal VLEV BF54XSBBC1533
+ ****temporarily using these values until data sheet is updated
+ */
+	VRPAIR(VLEV_085, 150000000),
+	VRPAIR(VLEV_090, 250000000),
+	VRPAIR(VLEV_110, 276000000),
+	VRPAIR(VLEV_115, 301000000),
+	VRPAIR(VLEV_120, 525000000),
+	VRPAIR(VLEV_125, 550000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *cm_bf548_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 	&rtc_device,
 #endif
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index b00f68a..d1682bb 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -46,6 +46,7 @@
 #include <asm/dma.h>
 #include <asm/gpio.h>
 #include <asm/nand.h>
+#include <asm/dpmc.h>
 #include <asm/portmux.h>
 #include <asm/mach/bf54x_keys.h>
 #include <linux/input.h>
@@ -689,7 +690,38 @@
 	.resource = &bfin_gpios_resources,
 };
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+/*
+ * Internal VLEV BF54XSBBC1533
+ ****temporarily using these values until data sheet is updated
+ */
+	VRPAIR(VLEV_085, 150000000),
+	VRPAIR(VLEV_090, 250000000),
+	VRPAIR(VLEV_110, 276000000),
+	VRPAIR(VLEV_115, 301000000),
+	VRPAIR(VLEV_120, 525000000),
+	VRPAIR(VLEV_125, 550000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *ezkit_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 	&rtc_device,
 #endif
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index 9fd5809..466ef59 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -33,12 +33,15 @@
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
+#endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -339,8 +342,37 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 300000000),
+	VRPAIR(VLEV_095, 313000000),
+	VRPAIR(VLEV_100, 350000000),
+	VRPAIR(VLEV_105, 400000000),
+	VRPAIR(VLEV_110, 444000000),
+	VRPAIR(VLEV_115, 450000000),
+	VRPAIR(VLEV_120, 475000000),
+	VRPAIR(VLEV_125, 500000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *cm_bf561_devices[] __initdata = {
 
+	&bfin_dpmc,
+
 #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
 	&hitachi_fb_device,
 #endif
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 0d74b7d..61d8f76 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -39,6 +39,7 @@
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
+#include <asm/dpmc.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -443,7 +444,37 @@
 };
 #endif
 
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 300000000),
+	VRPAIR(VLEV_095, 313000000),
+	VRPAIR(VLEV_100, 350000000),
+	VRPAIR(VLEV_105, 400000000),
+	VRPAIR(VLEV_110, 444000000),
+	VRPAIR(VLEV_115, 450000000),
+	VRPAIR(VLEV_120, 475000000),
+	VRPAIR(VLEV_125, 500000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
 static struct platform_device *ezkit_devices[] __initdata = {
+
+	&bfin_dpmc,
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
 	&smc91x_device,
 #endif
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
index 393081e..422bfee 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -6,5 +6,6 @@
 	cache.o cacheinit.o entry.o \
 	interrupt.o lock.o irqpanic.o arch_checks.o ints-priority.o
 
-obj-$(CONFIG_PM)         += pm.o dpmc.o
-obj-$(CONFIG_CPU_FREQ)   += cpufreq.o
+obj-$(CONFIG_PM)          += pm.o dpmc_modes.o
+obj-$(CONFIG_CPU_FREQ)    += cpufreq.o
+obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index ed81e00..75cdad2 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -62,6 +62,14 @@
 	unsigned int tscale; /* change the divider on the core timer interrupt */
 } dpm_state_table[3];
 
+/*
+   normalized to maximum frequncy offset for CYCLES,
+   used in time-ts cycles clock source, but could be used
+   somewhere also.
+ */
+unsigned long long __bfin_cycles_off;
+unsigned int __bfin_cycles_mod;
+
 /**************************************************************************/
 
 static unsigned int bfin_getfreq(unsigned int cpu)
@@ -80,6 +88,7 @@
 	unsigned int index, plldiv, tscale;
 	unsigned long flags, cclk_hz;
 	struct cpufreq_freqs freqs;
+	cycles_t cycles;
 
 	if (cpufreq_frequency_table_target(policy, bfin_freq_table,
 		 target_freq, relation, &index))
@@ -101,8 +110,14 @@
 		bfin_write_PLL_DIV(plldiv);
 		/* we have to adjust the core timer, because it is using cclk */
 		bfin_write_TSCALE(tscale);
+		cycles = get_cycles();
 		SSYNC();
+	cycles += 10; /* ~10 cycles we loose after get_cycles() */
+	__bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
+	__bfin_cycles_mod = index;
 	local_irq_restore(flags);
+	/* TODO: just test case for cycles clock source, remove later */
+	pr_debug("cpufreq: done\n");
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
 	return 0;
@@ -119,22 +134,13 @@
 	unsigned long cclk, sclk, csel, min_cclk;
 	int index;
 
-#ifdef CONFIG_CYCLES_CLOCKSOURCE
-/*
- * Clocksource CYCLES is still CONTINUOUS but not longer MONOTONIC in case we enable
- * CPU frequency scaling, since CYCLES runs off Core Clock.
- */
-	printk(KERN_WARNING "CPU frequency scaling not supported: Clocksource not suitable\n"
-		return -ENODEV;
-#endif
-
 	if (policy->cpu != 0)
 		return -EINVAL;
 
 	cclk = get_cclk();
 	sclk = get_sclk();
 
-#if ANOMALY_05000273
+#if ANOMALY_05000273 || (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_DCACHE))
 	min_cclk = sclk * 2;
 #else
 	min_cclk = sclk;
diff --git a/arch/blackfin/mach-common/dpmc.c b/arch/blackfin/mach-common/dpmc.c
new file mode 100644
index 0000000..02c7efd
--- /dev/null
+++ b/arch/blackfin/mach-common/dpmc.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/cpufreq.h>
+
+#include <asm/delay.h>
+#include <asm/dpmc.h>
+
+#define DRIVER_NAME "bfin dpmc"
+
+#define dprintk(msg...) \
+	cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg)
+
+struct bfin_dpmc_platform_data *pdata;
+
+/**
+ *	bfin_set_vlev - Update VLEV field in VR_CTL Reg.
+ *			Avoid BYPASS sequence
+ */
+static void bfin_set_vlev(unsigned int vlev)
+{
+	unsigned pll_lcnt;
+
+	pll_lcnt = bfin_read_PLL_LOCKCNT();
+
+	bfin_write_PLL_LOCKCNT(1);
+	bfin_write_VR_CTL((bfin_read_VR_CTL() & ~VLEV) | vlev);
+	bfin_write_PLL_LOCKCNT(pll_lcnt);
+}
+
+/**
+ *	bfin_get_vlev - Get CPU specific VLEV from platform device data
+ */
+static unsigned int bfin_get_vlev(unsigned int freq)
+{
+	int i;
+
+	if (!pdata)
+		goto err_out;
+
+	freq >>= 16;
+
+	for (i = 0; i < pdata->tabsize; i++)
+		if (freq <= (pdata->tuple_tab[i] & 0xFFFF))
+			return pdata->tuple_tab[i] >> 16;
+
+err_out:
+	printk(KERN_WARNING "DPMC: No suitable CCLK VDDINT voltage pair found\n");
+	return VLEV_120;
+}
+
+#ifdef CONFIG_CPU_FREQ
+static int
+vreg_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
+{
+	struct cpufreq_freqs *freq = data;
+
+	if (val == CPUFREQ_PRECHANGE && freq->old < freq->new) {
+		bfin_set_vlev(bfin_get_vlev(freq->new));
+		udelay(pdata->vr_settling_time); /* Wait until Volatge settled */
+
+	} else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)
+		bfin_set_vlev(bfin_get_vlev(freq->new));
+
+	return 0;
+}
+
+static struct notifier_block vreg_cpufreq_notifier_block = {
+	.notifier_call	= vreg_cpufreq_notifier
+};
+#endif /* CONFIG_CPU_FREQ */
+
+/**
+ *	bfin_dpmc_probe -
+ *
+ */
+static int __devinit bfin_dpmc_probe(struct platform_device *pdev)
+{
+	if (pdev->dev.platform_data)
+		pdata = pdev->dev.platform_data;
+	else
+		return -EINVAL;
+
+	return cpufreq_register_notifier(&vreg_cpufreq_notifier_block,
+					 CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+/**
+ *	bfin_dpmc_remove -
+ */
+static int __devexit bfin_dpmc_remove(struct platform_device *pdev)
+{
+	pdata = NULL;
+	return cpufreq_unregister_notifier(&vreg_cpufreq_notifier_block,
+					 CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+struct platform_driver bfin_dpmc_device_driver = {
+	.probe   = bfin_dpmc_probe,
+	.remove  = __devexit_p(bfin_dpmc_remove),
+	.driver  = {
+		.name = DRIVER_NAME,
+	}
+};
+
+/**
+ *	bfin_dpmc_init - Init driver
+ */
+static int __init bfin_dpmc_init(void)
+{
+	return platform_driver_register(&bfin_dpmc_device_driver);
+}
+module_init(bfin_dpmc_init);
+
+/**
+ *	bfin_dpmc_exit - break down driver
+ */
+static void __exit bfin_dpmc_exit(void)
+{
+	platform_driver_unregister(&bfin_dpmc_device_driver);
+}
+module_exit(bfin_dpmc_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("cpu power management driver for Blackfin");
+MODULE_LICENSE("GPL");
diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc_modes.S
similarity index 82%
rename from arch/blackfin/mach-common/dpmc.S
rename to arch/blackfin/mach-common/dpmc_modes.S
index 9d45aa3..b7981d3 100644
--- a/arch/blackfin/mach-common/dpmc.S
+++ b/arch/blackfin/mach-common/dpmc_modes.S
@@ -1,30 +1,7 @@
 /*
- * File:         arch/blackfin/mach-common/dpmc.S
- * Based on:
- * Author:       LG Soft India
+ * Copyright 2004-2008 Analog Devices Inc.
  *
- * Created:      ?
- * Description:  Watchdog Timer APIs
- *
- * Modified:
- *               Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * 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.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Licensed under the GPL-2 or later.
  */
 
 #include <linux/linkage.h>
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index f2fb87e..038f70e 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -151,26 +151,62 @@
 ENDPROC(_ex_soft_bp)
 
 ENTRY(_ex_single_step)
+	/* If we just returned from an interrupt, the single step event is
+	   for the RTI instruction.  */
 	r7 = retx;
 	r6 = reti;
 	cc = r7 == r6;
-	if cc jump _bfin_return_from_exception
+	if cc jump _bfin_return_from_exception;
+
+	/* If we were in user mode, do the single step normally.  */
+	p5.l = lo(IPEND);
+	p5.h = hi(IPEND);
+	r6 = [p5];
+	r7 = 0xffe0 (z);
+	r7 = r7 & r6;
+	cc = r7 == 0;
+	if !cc jump 1f;
+
+	/* Single stepping only a single instruction, so clear the trace
+	 * bit here.  */
+	r7 = syscfg;
+	bitclr (r7, 0);
+	syscfg = R7;
+	jump _ex_trap_c;
+
+1:
+	/*
+	 * We were in an interrupt handler.  By convention, all of them save
+	 * SYSCFG with their first instruction, so by checking whether our
+	 * RETX points at the entry point, we can determine whether to allow
+	 * a single step, or whether to clear SYSCFG.
+	 *
+	 * First, find out the interrupt level and the event vector for it.
+	 */
+	p5.l = lo(EVT0);
+	p5.h = hi(EVT0);
+	p5 += -4;
+2:
+	r7 = rot r7 by -1;
+	p5 += 4;
+	if !cc jump 2b;
+
+	/* What we actually do is test for the _second_ instruction in the
+	 * IRQ handler.  That way, if there are insns following the restore
+	 * of SYSCFG after leaving the handler, we will not turn off SYSCFG
+	 * for them.  */
+
+	r7 = [p5];
+	r7 += 2;
+	r6 = RETX;
+	cc = R7 == R6;
+	if !cc jump _bfin_return_from_exception;
+
 	r7 = syscfg;
 	bitclr (r7, 0);
 	syscfg = R7;
 
-	p5.l = lo(IPEND);
-	p5.h = hi(IPEND);
-	r6 = [p5];
-	cc = bittst(r6, 5);
-	if !cc jump _ex_trap_c;
-	p4.l = lo(EVT5);
-	p4.h = hi(EVT5);
-	r6.h = _exception_to_level5;
-	r6.l = _exception_to_level5;
-	r7 = [p4];
-	cc = r6 == r7;
-	if !cc jump _ex_trap_c;
+	/* Fall through to _bfin_return_from_exception.  */
 ENDPROC(_ex_single_step)
 
 ENTRY(_bfin_return_from_exception)
@@ -234,20 +270,26 @@
 	p5.l = _saved_icplb_fault_addr;
 	[p5] = r7;
 
-	p4.l = __retx;
-	p4.h = __retx;
+	p4.l = _excpt_saved_stuff;
+	p4.h = _excpt_saved_stuff;
+
 	r6 = retx;
 	[p4] = r6;
-	p4.l = lo(SAFE_USER_INSTRUCTION);
-	p4.h = hi(SAFE_USER_INSTRUCTION);
-	retx = p4;
+
+	r6 = SYSCFG;
+	[p4 + 4] = r6;
+	BITCLR(r6, 0);
+	SYSCFG = r6;
 
 	/* Disable all interrupts, but make sure level 5 is enabled so
 	 * we can switch to that level.  Save the old mask.  */
 	cli r6;
-	p4.l = _excpt_saved_imask;
-	p4.h = _excpt_saved_imask;
-	[p4] = r6;
+	[p4 + 8] = r6;
+
+	p4.l = lo(SAFE_USER_INSTRUCTION);
+	p4.h = hi(SAFE_USER_INSTRUCTION);
+	retx = p4;
+
 	r6 = 0x3f;
 	sti r6;
 
@@ -295,6 +337,11 @@
          */
         SAVE_ALL_SYS
 
+	/* The dumping functions expect the return address in the RETI
+	 * slot.  */
+	r6 = retx;
+	[sp + PT_PC] = r6;
+
         r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
         SP += -12;
         call _double_fault_c;
@@ -307,16 +354,17 @@
 ENTRY(_exception_to_level5)
 	SAVE_ALL_SYS
 
-	p4.l = __retx;
-	p4.h = __retx;
+	p4.l = _excpt_saved_stuff;
+	p4.h = _excpt_saved_stuff;
 	r6 = [p4];
 	[sp + PT_PC] = r6;
 
+	r6 = [p4 + 4];
+	[sp + PT_SYSCFG] = r6;
+
 	/* Restore interrupt mask.  We haven't pushed RETI, so this
 	 * doesn't enable interrupts until we return from this handler.  */
-	p4.l = _excpt_saved_imask;
-	p4.h = _excpt_saved_imask;
-	r6 = [p4];
+	r6 = [p4 + 8];
 	sti r6;
 
 	/* Restore the hardware error vector.  */
@@ -1344,7 +1392,14 @@
 	.rept NR_syscalls-(.-_sys_call_table)/4
 	.long _sys_ni_syscall
 	.endr
-_excpt_saved_imask:
+
+	/*
+	 * Used to save the real RETX, IMASK and SYSCFG when temporarily
+	 * storing safe values across the transition from exception to IRQ5.
+	 */
+_excpt_saved_stuff:
+	.long 0;
+	.long 0;
 	.long 0;
 
 _exception_stack:
@@ -1358,7 +1413,3 @@
 _last_cplb_fault_retx:
 	.long 0;
 #endif
-	/* Used to save the real RETX when temporarily storing a safe
-	 * return address.  */
-__retx:
-	.long 0;
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
index 8b99841..a79fbd8 100644
--- a/arch/cris/kernel/sys_cris.c
+++ b/arch/cris/kernel/sys_cris.c
@@ -27,25 +27,6 @@
 #include <asm/uaccess.h>
 #include <asm/segment.h>
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage int sys_pipe(unsigned long __user * fildes)
-{
-        int fd[2];
-        int error;
-
-        lock_kernel();
-        error = do_pipe(fd);
-        unlock_kernel();
-        if (!error) {
-                if (copy_to_user(fildes, fd, 2*sizeof(int)))
-                        error = -EFAULT;
-        }
-        return error;
-}
-
 /* common code for old and new mmaps */
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index 6d7a80f..305ac85 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -76,26 +76,6 @@
 	return oldval;
 }
 
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way Unix traditionally does this, though.
- */
-asmlinkage int
-sys_pipe(unsigned long r0, unsigned long r1, unsigned long r2,
-	unsigned long r3, unsigned long r4, unsigned long r5,
-	unsigned long r6, struct pt_regs regs)
-{
-	int fd[2];
-	int error;
-
-	error = do_pipe(fd);
-	if (!error) {
-		if (copy_to_user((void __user *)r0, fd, 2*sizeof(int)))
-			error = -EFAULT;
-	}
-	return error;
-}
-
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags,
 	unsigned long fd, unsigned long pgoff)
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index fd4858e..75b8340 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -468,15 +468,26 @@
 			 * (if do_page_fault didn't fix the mapping,
                          * the writeback won't do good)
 			 */
+disable_wb:
 #ifdef DEBUG
 			printk(".. disabling wb2\n");
 #endif
 			if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
 				fp->un.fmt7.wb2s &= ~WBV_040;
+			if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
+				fp->un.fmt7.wb3s &= ~WBV_040;
 		}
-	} else if (send_fault_sig(&fp->ptregs) > 0) {
-		printk("68040 access error, ssw=%x\n", ssw);
-		trap_c(fp);
+	} else {
+		/* In case of a bus error we either kill the process or expect
+		 * the kernel to catch the fault, which then is also responsible
+		 * for cleaning up the mess.
+		 */
+		current->thread.signo = SIGBUS;
+		current->thread.faddr = fp->un.fmt7.faddr;
+		if (send_fault_sig(&fp->ptregs) >= 0)
+			printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
+			       fp->un.fmt7.faddr);
+		goto disable_wb;
 	}
 
 	do_040writebacks(fp);
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 735a49b..ad3e3ba 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -48,9 +48,6 @@
 struct mac_booter_data mac_bi_data;
 int mac_bisize = sizeof mac_bi_data;
 
-struct mac_hw_present mac_hw_present;
-EXPORT_SYMBOL(mac_hw_present);
-
 /* New m68k bootinfo stuff and videobase */
 
 extern int m68k_num_memory;
@@ -817,27 +814,6 @@
 		m68k_ramdisk.addr, m68k_ramdisk.size);
 #endif
 
-	/*
-	 * TODO: set the various fields in macintosh_config->hw_present here!
-	 */
-	switch (macintosh_config->scsi_type) {
-	case MAC_SCSI_OLD:
-		MACHW_SET(MAC_SCSI_80);
-		break;
-	case MAC_SCSI_QUADRA:
-	case MAC_SCSI_QUADRA2:
-	case MAC_SCSI_QUADRA3:
-		MACHW_SET(MAC_SCSI_96);
-		if ((macintosh_config->ident == MAC_MODEL_Q900) ||
-		    (macintosh_config->ident == MAC_MODEL_Q950))
-			MACHW_SET(MAC_SCSI_96_2);
-		break;
-	default:
-		printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n");
-		MACHW_SET(MAC_SCSI_80);
-		break;
-	}
-
 	iop_init();
 	via_init();
 	oss_init();
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 07eb4c4..8e84415 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -671,6 +671,9 @@
 
 endchoice
 
+if COLDFIRE
+source "kernel/Kconfig.preempt"
+endif
 source "mm/Kconfig"
 
 endmenu
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 5592e0b..93e69236 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -114,6 +114,16 @@
 		*(__kcrctab_gpl)
 		__stop___kcrctab_gpl = .;
 
+		/* Kernel symbol table: Normal unused symbols */
+		__start___kcrctab_unused = .;
+		*(__kcrctab_unused)
+		__stop___kcrctab_unused = .;
+
+		/* Kernel symbol table: GPL-only unused symbols */
+		__start___kcrctab_unused_gpl = .;
+		*(__kcrctab_unused_gpl)
+		__stop___kcrctab_unused_gpl = .;
+
 		/* Kernel symbol table: GPL-future symbols */
 		__start___kcrctab_gpl_future = .;
 		*(__kcrctab_gpl_future)
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
index 90e2d7a..dd0e19d 100644
--- a/arch/mips/au1000/common/Makefile
+++ b/arch/mips/au1000/common/Makefile
@@ -1,9 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
-# Makefile for the Alchemy Au1000 CPU, generic files.
+# Makefile for the Alchemy Au1xx0 CPUs, generic files.
 #
 
 obj-y += prom.o irq.o puts.o time.o reset.o \
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
index 37a10a0..c7ca159 100644
--- a/arch/mips/au1000/common/au1xxx_irqmap.c
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c
@@ -40,20 +40,20 @@
 struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
 
 #if defined(CONFIG_SOC_AU1000)
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -62,32 +62,32 @@
 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
 
 #elif defined(CONFIG_SOC_AU1500)
 
-	{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -100,26 +100,26 @@
 	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
 
 #elif defined(CONFIG_SOC_AU1100)
 
-	{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -128,33 +128,33 @@
 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	/*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/
-	{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+	/* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */
+	{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
 
 #elif defined(CONFIG_SOC_AU1550)
 
-	{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -163,26 +163,26 @@
 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
+	{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
 
 #elif defined(CONFIG_SOC_AU1200)
 
-	{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
-	{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
-	{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
@@ -191,10 +191,10 @@
 	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
+	{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0 },
 	{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
-	{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 },
 
 #else
 #error "Error: Unknown Alchemy SOC"
@@ -203,4 +203,3 @@
 };
 
 int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map);
-
diff --git a/arch/mips/au1000/common/clocks.c b/arch/mips/au1000/common/clocks.c
index 3ce6cac..46f8ee0 100644
--- a/arch/mips/au1000/common/clocks.c
+++ b/arch/mips/au1000/common/clocks.c
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Simple Au1000 clocks routines.
+ *	Simple Au1xx0 clocks routines.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *		ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -30,8 +29,8 @@
 #include <linux/module.h>
 #include <asm/mach-au1x00/au1000.h>
 
-static unsigned int au1x00_clock; // Hz
-static unsigned int lcd_clock;    // KHz
+static unsigned int au1x00_clock; /*  Hz */
+static unsigned int lcd_clock;    /* KHz */
 static unsigned long uart_baud_base;
 
 /*
@@ -47,8 +46,6 @@
 	return au1x00_clock;
 }
 
-
-
 /*
  * The UART baud base is not known at compile time ... if
  * we want to be able to use the same code on different
@@ -73,24 +70,23 @@
 void set_au1x00_lcd_clock(void)
 {
 	unsigned int static_cfg0;
-	unsigned int sys_busclk =
-		(get_au1x00_speed()/1000) /
-		((int)(au_readl(SYS_POWERCTRL)&0x03) + 2);
+	unsigned int sys_busclk = (get_au1x00_speed() / 1000) /
+				  ((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2);
 
 	static_cfg0 = au_readl(MEM_STCFG0);
 
-	if (static_cfg0 & (1<<11))
+	if (static_cfg0 & (1 << 11))
 		lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
 	else
 		lcd_clock = sys_busclk / 4;
 
 	if (lcd_clock > 50000) /* Epson MAX */
-		printk("warning: LCD clock too high (%d KHz)\n", lcd_clock);
+		printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n",
+				    lcd_clock);
 }
 
 unsigned int get_au1x00_lcd_clock(void)
 {
 	return lcd_clock;
 }
-
 EXPORT_SYMBOL(get_au1x00_lcd_clock);
diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
index 8c93a05..ba6430b 100644
--- a/arch/mips/au1000/common/cputable.c
+++ b/arch/mips/au1000/common/cputable.c
@@ -14,7 +14,7 @@
 
 #include <asm/mach-au1x00/au1000.h>
 
-struct cpu_spec* cur_cpu_spec[NR_CPUS];
+struct cpu_spec *cur_cpu_spec[NR_CPUS];
 
 /* With some thought, we can probably use the mask to reduce the
  * size of the table.
@@ -39,8 +39,7 @@
 	{ 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 }
 };
 
-void
-set_cpuspec(void)
+void set_cpuspec(void)
 {
 	struct	cpu_spec *sp;
 	u32	prid;
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index 53377df..42d5552 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -53,12 +53,11 @@
  */
 static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
 
-/* I couldn't find a macro that did this......
-*/
+/* I couldn't find a macro that did this... */
 #define ALIGN_ADDR(x, a)	((((u32)(x)) + (a-1)) & ~(a-1))
 
 static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
-static int dbdma_initialized=0;
+static int dbdma_initialized;
 static void au1xxx_dbdma_init(void);
 
 static dbdev_tab_t dbdev_tab[] = {
@@ -149,7 +148,7 @@
 
 	{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
 
-#endif // CONFIG_SOC_AU1200
+#endif /* CONFIG_SOC_AU1200 */
 
 	{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
 	{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
@@ -177,8 +176,7 @@
 
 static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
 
-static dbdev_tab_t *
-find_dbdev_id(u32 id)
+static dbdev_tab_t *find_dbdev_id(u32 id)
 {
 	int i;
 	dbdev_tab_t *p;
@@ -190,29 +188,27 @@
 	return NULL;
 }
 
-void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
+void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
 {
-        return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+	return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 }
 EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
 
-u32
-au1xxx_ddma_add_device(dbdev_tab_t *dev)
+u32 au1xxx_ddma_add_device(dbdev_tab_t *dev)
 {
 	u32 ret = 0;
-	dbdev_tab_t *p=NULL;
-	static u16 new_id=0x1000;
+	dbdev_tab_t *p;
+	static u16 new_id = 0x1000;
 
 	p = find_dbdev_id(~0);
-	if ( NULL != p )
-	{
+	if (NULL != p) {
 		memcpy(p, dev, sizeof(dbdev_tab_t));
 		p->dev_id = DSCR_DEV2CUSTOM_ID(new_id, dev->dev_id);
 		ret = p->dev_id;
 		new_id++;
 #if 0
-		printk("add_device: id:%x flags:%x padd:%x\n",
-				p->dev_id, p->dev_flags, p->dev_physaddr );
+		printk(KERN_DEBUG "add_device: id:%x flags:%x padd:%x\n",
+				  p->dev_id, p->dev_flags, p->dev_physaddr);
 #endif
 	}
 
@@ -220,10 +216,8 @@
 }
 EXPORT_SYMBOL(au1xxx_ddma_add_device);
 
-/* Allocate a channel and return a non-zero descriptor if successful.
-*/
-u32
-au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+/* Allocate a channel and return a non-zero descriptor if successful. */
+u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
        void (*callback)(int, void *), void *callparam)
 {
 	unsigned long   flags;
@@ -234,7 +228,8 @@
 	chan_tab_t	*ctp;
 	au1x_dma_chan_t *cp;
 
-	/* We do the intialization on the first channel allocation.
+	/*
+	 * We do the intialization on the first channel allocation.
 	 * We have to wait because of the interrupt handler initialization
 	 * which can't be done successfully during board set up.
 	 */
@@ -242,16 +237,17 @@
 		au1xxx_dbdma_init();
 	dbdma_initialized = 1;
 
-	if ((stp = find_dbdev_id(srcid)) == NULL)
+	stp = find_dbdev_id(srcid);
+	if (stp == NULL)
 		return 0;
-	if ((dtp = find_dbdev_id(destid)) == NULL)
+	dtp = find_dbdev_id(destid);
+	if (dtp == NULL)
 		return 0;
 
 	used = 0;
 	rv = 0;
 
-	/* Check to see if we can get both channels.
-	*/
+	/* Check to see if we can get both channels. */
 	spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
 	if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
 	     (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
@@ -261,35 +257,30 @@
 		     (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
 			/* Got destination */
 			dtp->dev_flags |= DEV_FLAGS_INUSE;
-		}
-		else {
-			/* Can't get dest.  Release src.
-			*/
+		} else {
+			/* Can't get dest.  Release src. */
 			stp->dev_flags &= ~DEV_FLAGS_INUSE;
 			used++;
 		}
-	}
-	else {
+	} else
 		used++;
-	}
 	spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
 
 	if (!used) {
-		/* Let's see if we can allocate a channel for it.
-		*/
+		/* Let's see if we can allocate a channel for it. */
 		ctp = NULL;
 		chan = 0;
 		spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
-		for (i=0; i<NUM_DBDMA_CHANS; i++) {
+		for (i = 0; i < NUM_DBDMA_CHANS; i++)
 			if (chan_tab_ptr[i] == NULL) {
-				/* If kmalloc fails, it is caught below same
+				/*
+				 * If kmalloc fails, it is caught below same
 				 * as a channel not available.
 				 */
 				ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
 				chan_tab_ptr[i] = ctp;
 				break;
 			}
-		}
 		spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
 
 		if (ctp != NULL) {
@@ -304,8 +295,7 @@
 			ctp->chan_callback = callback;
 			ctp->chan_callparam = callparam;
 
-			/* Initialize channel configuration.
-			*/
+			/* Initialize channel configuration. */
 			i = 0;
 			if (stp->dev_intlevel)
 				i |= DDMA_CFG_SED;
@@ -326,8 +316,7 @@
 			 * operations.
 			 */
 			rv = (u32)(&chan_tab_ptr[chan]);
-		}
-		else {
+		} else {
 			/* Release devices */
 			stp->dev_flags &= ~DEV_FLAGS_INUSE;
 			dtp->dev_flags &= ~DEV_FLAGS_INUSE;
@@ -337,11 +326,11 @@
 }
 EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
 
-/* Set the device width if source or destination is a FIFO.
+/*
+ * Set the device width if source or destination is a FIFO.
  * Should be 8, 16, or 32 bits.
  */
-u32
-au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
+u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
 {
 	u32		rv;
 	chan_tab_t	*ctp;
@@ -365,10 +354,8 @@
 }
 EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
 
-/* Allocate a descriptor ring, initializing as much as possible.
-*/
-u32
-au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+/* Allocate a descriptor ring, initializing as much as possible. */
+u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
 {
 	int			i;
 	u32			desc_base, srcid, destid;
@@ -378,43 +365,45 @@
 	dbdev_tab_t		*stp, *dtp;
 	au1x_ddma_desc_t	*dp;
 
-	/* I guess we could check this to be within the
+	/*
+	 * I guess we could check this to be within the
 	 * range of the table......
 	 */
 	ctp = *((chan_tab_t **)chanid);
 	stp = ctp->chan_src;
 	dtp = ctp->chan_dest;
 
-	/* The descriptors must be 32-byte aligned.  There is a
+	/*
+	 * The descriptors must be 32-byte aligned.  There is a
 	 * possibility the allocation will give us such an address,
 	 * and if we try that first we are likely to not waste larger
 	 * slabs of memory.
 	 */
 	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
-			GFP_KERNEL|GFP_DMA);
+				 GFP_KERNEL|GFP_DMA);
 	if (desc_base == 0)
 		return 0;
 
 	if (desc_base & 0x1f) {
-		/* Lost....do it again, allocate extra, and round
+		/*
+		 * Lost....do it again, allocate extra, and round
 		 * the address base.
 		 */
 		kfree((const void *)desc_base);
 		i = entries * sizeof(au1x_ddma_desc_t);
 		i += (sizeof(au1x_ddma_desc_t) - 1);
-		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
+		desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA);
+		if (desc_base == 0)
 			return 0;
 
 		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
 	}
 	dp = (au1x_ddma_desc_t *)desc_base;
 
-	/* Keep track of the base descriptor.
-	*/
+	/* Keep track of the base descriptor. */
 	ctp->chan_desc_base = dp;
 
-	/* Initialize the rings with as much information as we know.
-	 */
+	/* Initialize the rings with as much information as we know. */
 	srcid = stp->dev_id;
 	destid = dtp->dev_id;
 
@@ -426,11 +415,12 @@
 	cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
 	cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
 
-        /* is it mem to mem transfer? */
-        if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
-           ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) {
-               cmd0 |= DSCR_CMD0_MEM;
-        }
+	/* Is it mem to mem transfer? */
+	if (((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) ||
+	     (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
+	    ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) ||
+	     (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS)))
+		cmd0 |= DSCR_CMD0_MEM;
 
 	switch (stp->dev_devwidth) {
 	case 8:
@@ -458,15 +448,17 @@
 		break;
 	}
 
-	/* If the device is marked as an in/out FIFO, ensure it is
+	/*
+	 * If the device is marked as an in/out FIFO, ensure it is
 	 * set non-coherent.
 	 */
 	if (stp->dev_flags & DEV_FLAGS_IN)
-		cmd0 |= DSCR_CMD0_SN;		/* Source in fifo */
+		cmd0 |= DSCR_CMD0_SN;		/* Source in FIFO */
 	if (dtp->dev_flags & DEV_FLAGS_OUT)
-		cmd0 |= DSCR_CMD0_DN;		/* Destination out fifo */
+		cmd0 |= DSCR_CMD0_DN;		/* Destination out FIFO */
 
-	/* Set up source1.  For now, assume no stride and increment.
+	/*
+	 * Set up source1.  For now, assume no stride and increment.
 	 * A channel attribute update can change this later.
 	 */
 	switch (stp->dev_tsize) {
@@ -485,19 +477,19 @@
 		break;
 	}
 
-	/* If source input is fifo, set static address.
-	*/
+	/* If source input is FIFO, set static address.	*/
 	if (stp->dev_flags & DEV_FLAGS_IN) {
-		if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
+		if (stp->dev_flags & DEV_FLAGS_BURSTABLE)
 			src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
 		else
-		src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
-
+			src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
 	}
+
 	if (stp->dev_physaddr)
 		src0 = stp->dev_physaddr;
 
-	/* Set up dest1.  For now, assume no stride and increment.
+	/*
+	 * Set up dest1.  For now, assume no stride and increment.
 	 * A channel attribute update can change this later.
 	 */
 	switch (dtp->dev_tsize) {
@@ -516,22 +508,24 @@
 		break;
 	}
 
-	/* If destination output is fifo, set static address.
-	*/
+	/* If destination output is FIFO, set static address. */
 	if (dtp->dev_flags & DEV_FLAGS_OUT) {
-		if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
-	                dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
-				else
-		dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
+		if (dtp->dev_flags & DEV_FLAGS_BURSTABLE)
+			dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
+		else
+			dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
 	}
+
 	if (dtp->dev_physaddr)
 		dest0 = dtp->dev_physaddr;
 
 #if 0
-		printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
-			dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
+		printk(KERN_DEBUG "did:%x sid:%x cmd0:%x cmd1:%x source0:%x "
+				  "source1:%x dest0:%x dest1:%x\n",
+				  dtp->dev_id, stp->dev_id, cmd0, cmd1, src0,
+				  src1, dest0, dest1);
 #endif
-	for (i=0; i<entries; i++) {
+	for (i = 0; i < entries; i++) {
 		dp->dscr_cmd0 = cmd0;
 		dp->dscr_cmd1 = cmd1;
 		dp->dscr_source0 = src0;
@@ -545,49 +539,49 @@
 		dp++;
 	}
 
-	/* Make last descrptor point to the first.
-	*/
+	/* Make last descrptor point to the first. */
 	dp--;
 	dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base));
 	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
 
-	return (u32)(ctp->chan_desc_base);
+	return (u32)ctp->chan_desc_base;
 }
 EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
 
-/* Put a source buffer into the DMA ring.
+/*
+ * Put a source buffer into the DMA ring.
  * This updates the source pointer and byte count.  Normally used
  * for memory to fifo transfers.
  */
-u32
-_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
+u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
 {
 	chan_tab_t		*ctp;
 	au1x_ddma_desc_t	*dp;
 
-	/* I guess we could check this to be within the
+	/*
+	 * I guess we could check this to be within the
 	 * range of the table......
 	 */
-	ctp = *((chan_tab_t **)chanid);
+	ctp = *(chan_tab_t **)chanid;
 
-	/* We should have multiple callers for a particular channel,
+	/*
+	 * We should have multiple callers for a particular channel,
 	 * an interrupt doesn't affect this pointer nor the descriptor,
 	 * so no locking should be needed.
 	 */
 	dp = ctp->put_ptr;
 
-	/* If the descriptor is valid, we are way ahead of the DMA
+	/*
+	 * If the descriptor is valid, we are way ahead of the DMA
 	 * engine, so just return an error condition.
 	 */
-	if (dp->dscr_cmd0 & DSCR_CMD0_V) {
+	if (dp->dscr_cmd0 & DSCR_CMD0_V)
 		return 0;
-	}
 
-	/* Load up buffer address and byte count.
-	*/
+	/* Load up buffer address and byte count. */
 	dp->dscr_source0 = virt_to_phys(buf);
 	dp->dscr_cmd1 = nbytes;
-	/* Check flags  */
+	/* Check flags */
 	if (flags & DDMA_FLAGS_IE)
 		dp->dscr_cmd0 |= DSCR_CMD0_IE;
 	if (flags & DDMA_FLAGS_NOIE)
@@ -595,23 +589,21 @@
 
 	/*
 	 * There is an errata on the Au1200/Au1550 parts that could result
-	 * in "stale" data being DMA'd. It has to do with the snoop logic on
-	 * the dache eviction buffer.  NONCOHERENT_IO is on by default for
-	 * these parts. If it is fixedin the future, these dma_cache_inv will
+	 * in "stale" data being DMA'ed. It has to do with the snoop logic on
+	 * the cache eviction buffer.  DMA_NONCOHERENT is on by default for
+	 * these parts. If it is fixed in the future, these dma_cache_inv will
 	 * just be nothing more than empty macros. See io.h.
-	 * */
+	 */
 	dma_cache_wback_inv((unsigned long)buf, nbytes);
-        dp->dscr_cmd0 |= DSCR_CMD0_V;        /* Let it rip */
+	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
 	au_sync();
 	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
-        ctp->chan_ptr->ddma_dbell = 0;
+	ctp->chan_ptr->ddma_dbell = 0;
 
-	/* Get next descriptor pointer.
-	*/
+	/* Get next descriptor pointer.	*/
 	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-	/* return something not zero.
-	*/
+	/* Return something non-zero. */
 	return nbytes;
 }
 EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
@@ -654,81 +646,77 @@
 	dp->dscr_dest0 = virt_to_phys(buf);
 	dp->dscr_cmd1 = nbytes;
 #if 0
-	printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
-			dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
-			dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
+	printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+			  dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
+			  dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
 #endif
 	/*
 	 * There is an errata on the Au1200/Au1550 parts that could result in
-	 * "stale" data being DMA'd. It has to do with the snoop logic on the
-	 * dache eviction buffer. NONCOHERENT_IO is on by default for these
-	 * parts. If it is fixedin the future, these dma_cache_inv will just
+	 * "stale" data being DMA'ed. It has to do with the snoop logic on the
+	 * cache eviction buffer.  DMA_NONCOHERENT is on by default for these
+	 * parts. If it is fixed in the future, these dma_cache_inv will just
 	 * be nothing more than empty macros. See io.h.
-	 * */
+	 */
 	dma_cache_inv((unsigned long)buf, nbytes);
 	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
 	au_sync();
 	dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
-        ctp->chan_ptr->ddma_dbell = 0;
+	ctp->chan_ptr->ddma_dbell = 0;
 
-	/* Get next descriptor pointer.
-	*/
+	/* Get next descriptor pointer.	*/
 	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-	/* return something not zero.
-	*/
+	/* Return something non-zero. */
 	return nbytes;
 }
 EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
 
-/* Get a destination buffer into the DMA ring.
+/*
+ * Get a destination buffer into the DMA ring.
  * Normally used to get a full buffer from the ring during fifo
  * to memory transfers.  This does not set the valid bit, you will
  * have to put another destination buffer to keep the DMA going.
  */
-u32
-au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
+u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
 {
 	chan_tab_t		*ctp;
 	au1x_ddma_desc_t	*dp;
 	u32			rv;
 
-	/* I guess we could check this to be within the
+	/*
+	 * I guess we could check this to be within the
 	 * range of the table......
 	 */
 	ctp = *((chan_tab_t **)chanid);
 
-	/* We should have multiple callers for a particular channel,
+	/*
+	 * We should have multiple callers for a particular channel,
 	 * an interrupt doesn't affect this pointer nor the descriptor,
 	 * so no locking should be needed.
 	 */
 	dp = ctp->get_ptr;
 
-	/* If the descriptor is valid, we are way ahead of the DMA
+	/*
+	 * If the descriptor is valid, we are way ahead of the DMA
 	 * engine, so just return an error condition.
 	 */
 	if (dp->dscr_cmd0 & DSCR_CMD0_V)
 		return 0;
 
-	/* Return buffer address and byte count.
-	*/
+	/* Return buffer address and byte count. */
 	*buf = (void *)(phys_to_virt(dp->dscr_dest0));
 	*nbytes = dp->dscr_cmd1;
 	rv = dp->dscr_stat;
 
-	/* Get next descriptor pointer.
-	*/
+	/* Get next descriptor pointer.	*/
 	ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-	/* return something not zero.
-	*/
+	/* Return something non-zero. */
 	return rv;
 }
-
 EXPORT_SYMBOL_GPL(au1xxx_dbdma_get_dest);
 
-void
-au1xxx_dbdma_stop(u32 chanid)
+void au1xxx_dbdma_stop(u32 chanid)
 {
 	chan_tab_t	*ctp;
 	au1x_dma_chan_t *cp;
@@ -743,7 +731,7 @@
 		udelay(1);
 		halt_timeout++;
 		if (halt_timeout > 100) {
-			printk("warning: DMA channel won't halt\n");
+			printk(KERN_WARNING "warning: DMA channel won't halt\n");
 			break;
 		}
 	}
@@ -753,12 +741,12 @@
 }
 EXPORT_SYMBOL(au1xxx_dbdma_stop);
 
-/* Start using the current descriptor pointer.  If the dbdma encounters
- * a not valid descriptor, it will stop.  In this case, we can just
+/*
+ * Start using the current descriptor pointer.  If the DBDMA encounters
+ * a non-valid descriptor, it will stop.  In this case, we can just
  * continue by adding a buffer to the list and starting again.
  */
-void
-au1xxx_dbdma_start(u32 chanid)
+void au1xxx_dbdma_start(u32 chanid)
 {
 	chan_tab_t	*ctp;
 	au1x_dma_chan_t *cp;
@@ -773,8 +761,7 @@
 }
 EXPORT_SYMBOL(au1xxx_dbdma_start);
 
-void
-au1xxx_dbdma_reset(u32 chanid)
+void au1xxx_dbdma_reset(u32 chanid)
 {
 	chan_tab_t		*ctp;
 	au1x_ddma_desc_t	*dp;
@@ -784,14 +771,14 @@
 	ctp = *((chan_tab_t **)chanid);
 	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
 
-	/* Run through the descriptors and reset the valid indicator.
-	*/
+	/* Run through the descriptors and reset the valid indicator. */
 	dp = ctp->chan_desc_base;
 
 	do {
 		dp->dscr_cmd0 &= ~DSCR_CMD0_V;
-		/* reset our SW status -- this is used to determine
-		 * if a descriptor is in use by upper level SW. Since
+		/*
+		 * Reset our software status -- this is used to determine
+		 * if a descriptor is in use by upper level software. Since
 		 * posting can reset 'V' bit.
 		 */
 		dp->sw_status = 0;
@@ -800,8 +787,7 @@
 }
 EXPORT_SYMBOL(au1xxx_dbdma_reset);
 
-u32
-au1xxx_get_dma_residue(u32 chanid)
+u32 au1xxx_get_dma_residue(u32 chanid)
 {
 	chan_tab_t	*ctp;
 	au1x_dma_chan_t *cp;
@@ -810,18 +796,15 @@
 	ctp = *((chan_tab_t **)chanid);
 	cp = ctp->chan_ptr;
 
-	/* This is only valid if the channel is stopped.
-	*/
+	/* This is only valid if the channel is stopped. */
 	rv = cp->ddma_bytecnt;
 	au_sync();
 
 	return rv;
 }
-
 EXPORT_SYMBOL_GPL(au1xxx_get_dma_residue);
 
-void
-au1xxx_dbdma_chan_free(u32 chanid)
+void au1xxx_dbdma_chan_free(u32 chanid)
 {
 	chan_tab_t	*ctp;
 	dbdev_tab_t	*stp, *dtp;
@@ -842,8 +825,7 @@
 }
 EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
 
-static irqreturn_t
-dbdma_interrupt(int irq, void *dev_id)
+static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
 {
 	u32 intstat;
 	u32 chan_index;
@@ -859,13 +841,12 @@
 	cp = ctp->chan_ptr;
 	dp = ctp->cur_ptr;
 
-	/* Reset interrupt.
-	*/
+	/* Reset interrupt. */
 	cp->ddma_irq = 0;
 	au_sync();
 
 	if (ctp->chan_callback)
-		(ctp->chan_callback)(irq, ctp->chan_callparam);
+		ctp->chan_callback(irq, ctp->chan_callparam);
 
 	ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 	return IRQ_RETVAL(1);
@@ -890,47 +871,47 @@
 
 	if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
 			"Au1xxx dbdma", (void *)dbdma_gptr))
-		printk("Can't get 1550 dbdma irq");
+		printk(KERN_ERR "Can't get 1550 dbdma irq");
 }
 
-void
-au1xxx_dbdma_dump(u32 chanid)
+void au1xxx_dbdma_dump(u32 chanid)
 {
-	chan_tab_t		*ctp;
-	au1x_ddma_desc_t	*dp;
-	dbdev_tab_t		*stp, *dtp;
-	au1x_dma_chan_t *cp;
-		u32			i = 0;
+	chan_tab_t	 *ctp;
+	au1x_ddma_desc_t *dp;
+	dbdev_tab_t	 *stp, *dtp;
+	au1x_dma_chan_t  *cp;
+	u32 i		 = 0;
 
 	ctp = *((chan_tab_t **)chanid);
 	stp = ctp->chan_src;
 	dtp = ctp->chan_dest;
 	cp = ctp->chan_ptr;
 
-	printk("Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
-		(u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, dtp - dbdev_tab);
-	printk("desc base %x, get %x, put %x, cur %x\n",
-		(u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
-		(u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
+	printk(KERN_DEBUG "Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
+			  (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp,
+			  dtp - dbdev_tab);
+	printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n",
+			  (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
+			  (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
 
-	printk("dbdma chan %x\n", (u32)cp);
-	printk("cfg %08x, desptr %08x, statptr %08x\n",
-		cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
-	printk("dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
-		cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, cp->ddma_bytecnt);
+	printk(KERN_DEBUG "dbdma chan %x\n", (u32)cp);
+	printk(KERN_DEBUG "cfg %08x, desptr %08x, statptr %08x\n",
+			  cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
+	printk(KERN_DEBUG "dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
+			  cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat,
+			  cp->ddma_bytecnt);
 
-
-	/* Run through the descriptors
-	*/
+	/* Run through the descriptors */
 	dp = ctp->chan_desc_base;
 
 	do {
-                printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
-                        i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
-                printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
-                        dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
-                printk("stat %08x, nxtptr %08x\n",
-                        dp->dscr_stat, dp->dscr_nxtptr);
+		printk(KERN_DEBUG "Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
+				  i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+		printk(KERN_DEBUG "src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
+				  dp->dscr_source0, dp->dscr_source1,
+				  dp->dscr_dest0, dp->dscr_dest1);
+		printk(KERN_DEBUG "stat %08x, nxtptr %08x\n",
+				  dp->dscr_stat, dp->dscr_nxtptr);
 		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 	} while (dp != ctp->chan_desc_base);
 }
@@ -938,32 +919,33 @@
 /* Put a descriptor into the DMA ring.
  * This updates the source/destination pointers and byte count.
  */
-u32
-au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
 {
 	chan_tab_t *ctp;
 	au1x_ddma_desc_t *dp;
-	u32 nbytes=0;
+	u32 nbytes = 0;
 
-	/* I guess we could check this to be within the
-	* range of the table......
-	*/
+	/*
+	 * I guess we could check this to be within the
+	 * range of the table......
+	 */
 	ctp = *((chan_tab_t **)chanid);
 
-	/* We should have multiple callers for a particular channel,
-	* an interrupt doesn't affect this pointer nor the descriptor,
-	* so no locking should be needed.
-	*/
+	/*
+	 * We should have multiple callers for a particular channel,
+	 * an interrupt doesn't affect this pointer nor the descriptor,
+	 * so no locking should be needed.
+	 */
 	dp = ctp->put_ptr;
 
-	/* If the descriptor is valid, we are way ahead of the DMA
-	* engine, so just return an error condition.
-	*/
+	/*
+	 * If the descriptor is valid, we are way ahead of the DMA
+	 * engine, so just return an error condition.
+	 */
 	if (dp->dscr_cmd0 & DSCR_CMD0_V)
 		return 0;
 
-	/* Load up buffer addresses and byte count.
-	*/
+	/* Load up buffer addresses and byte count. */
 	dp->dscr_dest0 = dscr->dscr_dest0;
 	dp->dscr_source0 = dscr->dscr_source0;
 	dp->dscr_dest1 = dscr->dscr_dest1;
@@ -975,14 +957,11 @@
 	dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
 	ctp->chan_ptr->ddma_dbell = 0;
 
-	/* Get next descriptor pointer.
-	*/
+	/* Get next descriptor pointer.	*/
 	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
 
-	/* return something not zero.
-	*/
+	/* Return something non-zero. */
 	return nbytes;
 }
 
 #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
-
diff --git a/arch/mips/au1000/common/dbg_io.c b/arch/mips/au1000/common/dbg_io.c
index eae1bb2..af5be7d 100644
--- a/arch/mips/au1000/common/dbg_io.c
+++ b/arch/mips/au1000/common/dbg_io.c
@@ -1,3 +1,4 @@
+#include <linux/types.h>
 
 #include <asm/mach-au1x00/au1000.h>
 
@@ -8,12 +9,6 @@
  * uart to be used for debugging.
  */
 #define DEBUG_BASE  UART_DEBUG_BASE
-/**/
-
-/* we need uint32 uint8 */
-/* #include "types.h" */
-typedef         unsigned char uint8;
-typedef         unsigned int  uint32;
 
 #define         UART16550_BAUD_2400             2400
 #define         UART16550_BAUD_4800             4800
@@ -51,17 +46,15 @@
 #define UART_MOD_CNTRL	0x100	/* Module Control */
 
 /* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (au_readl(DEBUG_BASE + y) & 0xff)
-#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y))
+#define UART16550_READ(y)     (au_readl(DEBUG_BASE + y) & 0xff)
+#define UART16550_WRITE(y, z) (au_writel(z & 0xff, DEBUG_BASE + y))
 
 extern unsigned long calc_clock(void);
 
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
 {
-
-	if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
+	if (UART16550_READ(UART_MOD_CNTRL) != 0x3)
 		UART16550_WRITE(UART_MOD_CNTRL, 3);
-	}
 	calc_clock();
 
 	/* disable interrupts */
@@ -69,7 +62,7 @@
 
 	/* set up baud rate */
 	{
-		uint32 divisor;
+		u32 divisor;
 
 		/* set divisor */
 		divisor = get_au1x00_uart_baud_base() / baud;
@@ -80,9 +73,9 @@
 	UART16550_WRITE(UART_LCR, (data | parity | stop));
 }
 
-static int remoteDebugInitialized = 0;
+static int remoteDebugInitialized;
 
-uint8 getDebugChar(void)
+u8 getDebugChar(void)
 {
 	if (!remoteDebugInitialized) {
 		remoteDebugInitialized = 1;
@@ -92,15 +85,13 @@
 			  UART16550_STOP_1BIT);
 	}
 
-	while((UART16550_READ(UART_LSR) & 0x1) == 0);
+	while ((UART16550_READ(UART_LSR) & 0x1) == 0);
 	return UART16550_READ(UART_RX);
 }
 
 
-int putDebugChar(uint8 byte)
+int putDebugChar(u8 byte)
 {
-//	int i;
-
 	if (!remoteDebugInitialized) {
 		remoteDebugInitialized = 1;
 		debugInit(UART16550_BAUD_115200,
@@ -109,9 +100,8 @@
 			  UART16550_STOP_1BIT);
 	}
 
-	while ((UART16550_READ(UART_LSR)&0x40) == 0);
+	while ((UART16550_READ(UART_LSR) & 0x40) == 0);
 	UART16550_WRITE(UART_TX, byte);
-	//for (i=0;i<0xfff;i++);
 
 	return 1;
 }
diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
index 95f69ea..d6fbda2 100644
--- a/arch/mips/au1000/common/dma.c
+++ b/arch/mips/au1000/common/dma.c
@@ -1,12 +1,11 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *      A DMA channel allocator for Au1000. API is modeled loosely off of
+ *      A DMA channel allocator for Au1x00. API is modeled loosely off of
  *      linux/kernel/dma.c.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	stevel@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -39,7 +38,8 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1000_dma.h>
 
-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
+    defined(CONFIG_SOC_AU1100)
 /*
  * A note on resource allocation:
  *
@@ -56,7 +56,6 @@
  * returned from request_dma.
  */
 
-
 DEFINE_SPINLOCK(au1000_dma_spin_lock);
 
 struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
@@ -71,7 +70,7 @@
 };
 EXPORT_SYMBOL(au1000_dma_table);
 
-// Device FIFO addresses and default DMA modes
+/* Device FIFO addresses and default DMA modes */
 static const struct dma_dev {
 	unsigned int fifo_addr;
 	unsigned int dma_mode;
@@ -80,8 +79,8 @@
 	{UART0_ADDR + UART_RX, 0},
 	{0, 0},
 	{0, 0},
-	{AC97C_DATA, DMA_DW16 },          // coherent
-	{AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
+	{AC97C_DATA, DMA_DW16 },          /* coherent */
+	{AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */
 	{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
 	{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
 	{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
@@ -101,10 +100,10 @@
 	struct dma_chan *chan;
 
 	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
-		if ((chan = get_dma_chan(i)) != NULL) {
+		chan = get_dma_chan(i);
+		if (chan != NULL)
 			len += sprintf(buf + len, "%2d: %s\n",
 				       i, chan->dev_str);
-		}
 	}
 
 	if (fpos >= len) {
@@ -113,18 +112,19 @@
 		return 0;
 	}
 	*start = buf + fpos;
-	if ((len -= fpos) > length)
+	len -= fpos;
+	if (len > length)
 		return length;
 	*eof = 1;
 	return len;
 }
 
-// Device FIFO addresses and default DMA modes - 2nd bank
+/* Device FIFO addresses and default DMA modes - 2nd bank */
 static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
-	{SD0_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
-	{SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8},	// coherent
-	{SD1_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
-	{SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}	// coherent
+	{ SD0_XMIT_FIFO, DMA_DS | DMA_DW8 },		/* coherent */
+	{ SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 },	/* coherent */
+	{ SD1_XMIT_FIFO, DMA_DS | DMA_DW8 },		/* coherent */
+	{ SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }	/* coherent */
 };
 
 void dump_au1000_dma_channel(unsigned int dmanr)
@@ -150,7 +150,6 @@
 	       au_readl(chan->io + DMA_BUFFER1_COUNT));
 }
 
-
 /*
  * Finds a free channel, and binds the requested device to it.
  * Returns the allocated channel number, or negative on error.
@@ -169,14 +168,14 @@
 	if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
 		return -EINVAL;
 #else
- 	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
 		return -EINVAL;
 #endif
 
-	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
 		if (au1000_dma_table[i].dev_id < 0)
 			break;
-	}
+
 	if (i == NUM_AU1000_DMA_CHANNELS)
 		return -ENODEV;
 
@@ -185,15 +184,15 @@
 	if (dev_id >= DMA_NUM_DEV) {
 		dev_id -= DMA_NUM_DEV;
 		dev = &dma_dev_table_bank2[dev_id];
-	} else {
+	} else
 		dev = &dma_dev_table[dev_id];
-	}
 
 	if (irqhandler) {
 		chan->irq = AU1000_DMA_INT_BASE + i;
 		chan->irq_dev = irq_dev_id;
-		if ((ret = request_irq(chan->irq, irqhandler, irqflags,
-				       dev_str, chan->irq_dev))) {
+		ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
+				  chan->irq_dev);
+		if (ret) {
 			chan->irq = 0;
 			chan->irq_dev = NULL;
 			return ret;
@@ -203,7 +202,7 @@
 		chan->irq_dev = NULL;
 	}
 
-	// fill it in
+	/* fill it in */
 	chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
 	chan->dev_id = dev_id;
 	chan->dev_str = dev_str;
@@ -220,8 +219,9 @@
 void free_au1000_dma(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan) {
-		printk("Trying to free DMA%d\n", dmanr);
+		printk(KERN_ERR "Error trying to free DMA%d\n", dmanr);
 		return;
 	}
 
@@ -235,4 +235,4 @@
 }
 EXPORT_SYMBOL(free_au1000_dma);
 
-#endif // AU1000 AU1500 AU1100
+#endif /* AU1000 AU1500 AU1100 */
diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c
index 5254525..b485d94 100644
--- a/arch/mips/au1000/common/gpio.c
+++ b/arch/mips/au1000/common/gpio.c
@@ -69,7 +69,7 @@
 
 static int au1xxx_gpio1_read(unsigned gpio)
 {
-	return ((gpio1->pinstaterd >> gpio) & 0x01);
+	return (gpio1->pinstaterd >> gpio) & 0x01;
 }
 
 static void au1xxx_gpio1_write(unsigned gpio, int value)
@@ -104,7 +104,6 @@
 	else
 		return au1xxx_gpio1_read(gpio);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_get_value);
 
 void au1xxx_gpio_set_value(unsigned gpio, int value)
@@ -118,7 +117,6 @@
 	else
 		au1xxx_gpio1_write(gpio, value);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_set_value);
 
 int au1xxx_gpio_direction_input(unsigned gpio)
@@ -132,7 +130,6 @@
 
 	return au1xxx_gpio1_direction_input(gpio);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_direction_input);
 
 int au1xxx_gpio_direction_output(unsigned gpio, int value)
@@ -146,5 +143,4 @@
 
 	return au1xxx_gpio1_direction_output(gpio, value);
 }
-
 EXPORT_SYMBOL(au1xxx_gpio_direction_output);
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index f062699..40c6cec 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -210,10 +210,8 @@
 	au_sync();
 }
 
-
 static inline void mask_and_ack_level_irq(unsigned int irq_nr)
 {
-
 	local_disable_irq(irq_nr);
 	au_sync();
 #if defined(CONFIG_MIPS_PB1000)
@@ -263,14 +261,14 @@
 	unsigned long flags, new_mask;
 
 	spin_lock_irqsave(&irq_lock, flags);
-	for (i = 0; i < 32; i++) {
+	for (i = 0; i < 32; i++)
 		if (mask & (1 << i)) {
 			if (controller)
 				local_enable_irq(i + 32);
 			else
 				local_enable_irq(i);
 		}
-	}
+
 	if (controller)
 		new_mask = au_readl(IC1_MASKSET);
 	else
diff --git a/arch/mips/au1000/common/pci.c b/arch/mips/au1000/common/pci.c
index 7e966b3..7866cf5 100644
--- a/arch/mips/au1000/common/pci.c
+++ b/arch/mips/au1000/common/pci.c
@@ -2,9 +2,8 @@
  * BRIEF MODULE DESCRIPTION
  *	Alchemy/AMD Au1x00 PCI support.
  *
- * Copyright 2001-2003, 2007 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
  *
@@ -86,9 +85,9 @@
 		u32 prid = read_c0_prid();
 
 		if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
-		       au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
-			         Au1500_PCI_CFG);
-		       printk("Non-coherent PCI accesses enabled\n");
+			au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
+				  Au1500_PCI_CFG);
+			printk(KERN_INFO "Non-coherent PCI accesses enabled\n");
 		}
 	}
 #endif
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 31d2a22..8cae775 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -269,8 +269,8 @@
 #ifdef SMBUS_PSC_BASE
 static struct resource pbdb_smbus_resources[] = {
 	{
-		.start	= SMBUS_PSC_BASE,
-		.end	= SMBUS_PSC_BASE + 0x24 - 1,
+		.start	= CPHYSADDR(SMBUS_PSC_BASE),
+		.end	= CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
 		.flags	= IORESOURCE_MEM,
 	},
 };
@@ -302,16 +302,17 @@
 #endif
 };
 
-int __init au1xxx_platform_init(void)
+static int __init au1xxx_platform_init(void)
 {
 	unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
 	int i;
 
 	/* Fill up uartclk. */
-	for (i = 0; au1x00_uart_data[i].flags ; i++)
+	for (i = 0; au1x00_uart_data[i].flags; i++)
 		au1x00_uart_data[i].uartclk = uartclk;
 
-	return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
+	return platform_add_devices(au1xxx_platform_devices,
+				    ARRAY_SIZE(au1xxx_platform_devices));
 }
 
 arch_initcall(au1xxx_platform_init);
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
index a8cd2c1..2166b9e 100644
--- a/arch/mips/au1000/common/power.c
+++ b/arch/mips/au1000/common/power.c
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Au1000 Power Management routines.
+ *	Au1xx0 Power Management routines.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *		ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  *  Some of the routines are right out of init/main.c, whose
  *  copyrights apply here.
@@ -43,10 +42,10 @@
 #ifdef CONFIG_PM
 
 #define DEBUG 1
-#ifdef DEBUG
-#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __func__, ## args)
+#ifdef	DEBUG
+#define DPRINTK(fmt, args...)	printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
 #else
-#  define DPRINTK(fmt, args...)
+#define DPRINTK(fmt, args...)
 #endif
 
 static void au1000_calibrate_delay(void);
@@ -57,7 +56,8 @@
 
 static DEFINE_SPINLOCK(pm_lock);
 
-/* We need to save/restore a bunch of core registers that are
+/*
+ * We need to save/restore a bunch of core registers that are
  * either volatile or reset to some state across a processor sleep.
  * If reading a register doesn't provide a proper result for a
  * later restore, we have to provide a function for loading that
@@ -78,24 +78,25 @@
 static unsigned int	sleep_usbdev_enable;
 static unsigned int	sleep_static_memctlr[4][3];
 
-/* Define this to cause the value you write to /proc/sys/pm/sleep to
+/*
+ * Define this to cause the value you write to /proc/sys/pm/sleep to
  * set the TOY timer for the amount of time you want to sleep.
  * This is done mainly for testing, but may be useful in other cases.
  * The value is number of 32KHz ticks to sleep.
  */
 #define SLEEP_TEST_TIMEOUT 1
-#ifdef SLEEP_TEST_TIMEOUT
-static	int	sleep_ticks;
+#ifdef	SLEEP_TEST_TIMEOUT
+static int sleep_ticks;
 void wakeup_counter0_set(int ticks);
 #endif
 
-static void
-save_core_regs(void)
+static void save_core_regs(void)
 {
 	extern void save_au1xxx_intctl(void);
 	extern void pm_eth0_shutdown(void);
 
-	/* Do the serial ports.....these really should be a pm_*
+	/*
+	 * Do the serial ports.....these really should be a pm_*
 	 * registered function by the driver......but of course the
 	 * standard serial driver doesn't understand our Au1xxx
 	 * unique registers.
@@ -106,27 +107,24 @@
 	sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
 	sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
 
-	/* Shutdown USB host/device.
-	*/
+	/* Shutdown USB host/device. */
 	sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
 
-	/* There appears to be some undocumented reset register....
-	*/
+	/* There appears to be some undocumented reset register.... */
 	au_writel(0, 0xb0100004); au_sync();
 	au_writel(0, USB_HOST_CONFIG); au_sync();
 
 	sleep_usbdev_enable = au_readl(USBD_ENABLE);
 	au_writel(0, USBD_ENABLE); au_sync();
 
-	/* Save interrupt controller state.
-	*/
+	/* Save interrupt controller state. */
 	save_au1xxx_intctl();
 
-	/* Clocks and PLLs.
-	*/
+	/* Clocks and PLLs. */
 	sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
 
-	/* We don't really need to do this one, but unless we
+	/*
+	 * We don't really need to do this one, but unless we
 	 * write it again it won't have a valid value if we
 	 * happen to read it.
 	 */
@@ -134,8 +132,7 @@
 
 	sleep_pin_function = au_readl(SYS_PINFUNC);
 
-	/* Save the static memory controller configuration.
-	*/
+	/* Save the static memory controller configuration. */
 	sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
 	sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
 	sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
@@ -150,8 +147,7 @@
 	sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
 }
 
-static void
-restore_core_regs(void)
+static void restore_core_regs(void)
 {
 	extern void restore_au1xxx_intctl(void);
 	extern void wakeup_counter0_adjust(void);
@@ -160,8 +156,7 @@
 	au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
 	au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
 
-	/* Restore the static memory controller configuration.
-	*/
+	/* Restore the static memory controller configuration. */
 	au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
 	au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
 	au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
@@ -175,7 +170,8 @@
 	au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
 	au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
 
-	/* Enable the UART if it was enabled before sleep.
+	/*
+	 * Enable the UART if it was enabled before sleep.
 	 * I guess I should define module control bits........
 	 */
 	if (sleep_uart0_enable & 0x02) {
@@ -202,7 +198,7 @@
 int au_sleep(void)
 {
 	unsigned long wakeup, flags;
-	extern	void	save_and_sleep(void);
+	extern void save_and_sleep(void);
 
 	spin_lock_irqsave(&pm_lock, flags);
 
@@ -210,23 +206,22 @@
 
 	flush_cache_all();
 
-	/** The code below is all system dependent and we should probably
+	/**
+	 ** The code below is all system dependent and we should probably
 	 ** have a function call out of here to set this up.  You need
 	 ** to configure the GPIO or timer interrupts that will bring
 	 ** you out of sleep.
 	 ** For testing, the TOY counter wakeup is useful.
 	 **/
-
 #if 0
 	au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
 
-	/* gpio 6 can cause a wake up event */
+	/* GPIO 6 can cause a wake up event */
 	wakeup = au_readl(SYS_WAKEMSK);
 	wakeup &= ~(1 << 8);	/* turn off match20 wakeup */
-	wakeup |= 1 << 6;	/* turn on gpio 6 wakeup   */
+	wakeup |= 1 << 6;	/* turn on  GPIO  6 wakeup */
 #else
-	/* For testing, allow match20 to wake us up.
-	*/
+	/* For testing, allow match20 to wake us up. */
 #ifdef SLEEP_TEST_TIMEOUT
 	wakeup_counter0_set(sleep_ticks);
 #endif
@@ -240,7 +235,8 @@
 
 	save_and_sleep();
 
-	/* after a wakeup, the cpu vectors back to 0x1fc00000 so
+	/*
+	 * After a wakeup, the cpu vectors back to 0x1fc00000, so
 	 * it's up to the boot code to get us back here.
 	 */
 	restore_core_regs();
@@ -248,24 +244,22 @@
 	return 0;
 }
 
-static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
-		       void __user *buffer, size_t * len, loff_t *ppos)
+static int pm_do_sleep(ctl_table *ctl, int write, struct file *file,
+		       void __user *buffer, size_t *len, loff_t *ppos)
 {
 #ifdef SLEEP_TEST_TIMEOUT
 #define TMPBUFLEN2 16
 	char buf[TMPBUFLEN2], *p;
 #endif
 
-	if (!write) {
+	if (!write)
 		*len = 0;
-	} else {
+	else {
 #ifdef SLEEP_TEST_TIMEOUT
-		if (*len > TMPBUFLEN2 - 1) {
+		if (*len > TMPBUFLEN2 - 1)
 			return -EFAULT;
-		}
-		if (copy_from_user(buf, buffer, *len)) {
+		if (copy_from_user(buf, buffer, *len))
 			return -EFAULT;
-		}
 		buf[*len] = 0;
 		p = buf;
 		sleep_ticks = simple_strtoul(p, &p, 0);
@@ -276,8 +270,8 @@
 	return 0;
 }
 
-static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
-		      void __user *buffer, size_t * len, loff_t *ppos)
+static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
+		      void __user *buffer, size_t *len, loff_t *ppos)
 {
 	int retval = 0, i;
 	unsigned long val, pll;
@@ -285,14 +279,14 @@
 #define MAX_CPU_FREQ 396
 	char buf[TMPBUFLEN], *p;
 	unsigned long flags, intc0_mask, intc1_mask;
-	unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
-	    old_refresh;
+	unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh;
 	unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
+	unsigned long baud_rate;
 
 	spin_lock_irqsave(&pm_lock, flags);
-	if (!write) {
+	if (!write)
 		*len = 0;
-	} else {
+	else {
 		/* Parse the new frequency */
 		if (*len > TMPBUFLEN - 1) {
 			spin_unlock_irqrestore(&pm_lock, flags);
@@ -312,7 +306,7 @@
 
 		pll = val / 12;
 		if ((pll > 33) || (pll < 7)) {	/* 396 MHz max, 84 MHz min */
-			/* revisit this for higher speed cpus */
+			/* Revisit this for higher speed CPUs */
 			spin_unlock_irqrestore(&pm_lock, flags);
 			return -EFAULT;
 		}
@@ -321,30 +315,28 @@
 		old_cpu_freq = get_au1x00_speed();
 
 		new_cpu_freq = pll * 12 * 1000000;
-	        new_baud_base =  (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
+	        new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)
+							    & 0x03) + 2) * 16));
 		set_au1x00_speed(new_cpu_freq);
 		set_au1x00_uart_baud_base(new_baud_base);
 
 		old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
-		new_refresh =
-		    ((old_refresh * new_cpu_freq) /
-		     old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
+		new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) |
+			      (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
 
 		au_writel(pll, SYS_CPUPLL);
 		au_sync_delay(1);
 		au_writel(new_refresh, MEM_SDREFCFG);
 		au_sync_delay(1);
 
-		for (i = 0; i < 4; i++) {
-			if (au_readl
-			    (UART_BASE + UART_MOD_CNTRL +
-			     i * 0x00100000) == 3) {
-				old_clk =
-				    au_readl(UART_BASE + UART_CLK +
-					  i * 0x00100000);
-				// baud_rate = baud_base/clk
+		for (i = 0; i < 4; i++)
+			if (au_readl(UART_BASE + UART_MOD_CNTRL +
+				     i * 0x00100000) == 3) {
+				old_clk = au_readl(UART_BASE + UART_CLK +
+						   i * 0x00100000);
 				baud_rate = old_baud_base / old_clk;
-				/* we won't get an exact baud rate and the error
+				/*
+				 * We won't get an exact baud rate and the error
 				 * could be significant enough that our new
 				 * calculation will result in a clock that will
 				 * give us a baud rate that's too far off from
@@ -359,18 +351,14 @@
 				else if (baud_rate > 17000)
 					baud_rate = 19200;
 				else
-					(baud_rate = 9600);
-				// new_clk = new_baud_base/baud_rate
+					baud_rate = 9600;
 				new_clk = new_baud_base / baud_rate;
-				au_writel(new_clk,
-				       UART_BASE + UART_CLK +
-				       i * 0x00100000);
+				au_writel(new_clk, UART_BASE + UART_CLK +
+					  i * 0x00100000);
 				au_sync_delay(10);
 			}
-		}
 	}
 
-
 	/*
 	 * We don't want _any_ interrupts other than match20. Otherwise our
 	 * au1000_calibrate_delay() calculation will be off, potentially a lot.
@@ -428,14 +416,15 @@
 
 __initcall(pm_init);
 
-
 /*
  * This is right out of init/main.c
  */
 
-/* This is the number of bits of precision for the loops_per_jiffy.  Each
-   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
-   better than 1% */
+/*
+ * This is the number of bits of precision for the loops_per_jiffy.
+ * Each bit takes on average 1.5/HZ seconds.  This (like the original)
+ * is a little better than 1%.
+ */
 #define LPS_PREC 8
 
 static void au1000_calibrate_delay(void)
@@ -443,14 +432,14 @@
 	unsigned long ticks, loopbit;
 	int lps_precision = LPS_PREC;
 
-	loops_per_jiffy = (1 << 12);
+	loops_per_jiffy = 1 << 12;
 
 	while (loops_per_jiffy <<= 1) {
-		/* wait for "start of" clock tick */
+		/* Wait for "start of" clock tick */
 		ticks = jiffies;
 		while (ticks == jiffies)
 			/* nothing */ ;
-		/* Go .. */
+		/* Go ... */
 		ticks = jiffies;
 		__delay(loops_per_jiffy);
 		ticks = jiffies - ticks;
@@ -458,8 +447,10 @@
 			break;
 	}
 
-/* Do a binary approximation to get loops_per_jiffy set to equal one clock
-   (up to lps_precision bits) */
+	/*
+	 * Do a binary approximation to get loops_per_jiffy set to be equal
+	 * one clock (up to lps_precision bits)
+	 */
 	loops_per_jiffy >>= 1;
 	loopbit = loops_per_jiffy;
 	while (lps_precision-- && (loopbit >>= 1)) {
@@ -472,4 +463,4 @@
 			loops_per_jiffy &= ~loopbit;
 	}
 }
-#endif				/* CONFIG_PM */
+#endif	/* CONFIG_PM */
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index f10af82..18b310b 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *    PROM library initialisation code, supports YAMON and U-Boot.
  *
- * Copyright 2000, 2001, 2006 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2000-2001, 2006, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/xx files.
@@ -57,7 +56,7 @@
 	actr = 1; /* Always ignore argv[0] */
 
 	cp = &(arcs_cmdline[0]);
-	while(actr < prom_argc) {
+	while (actr < prom_argc) {
 		strcpy(cp, prom_argv[actr]);
 		cp += strlen(prom_argv[actr]);
 		*cp++ = ' ';
@@ -84,10 +83,8 @@
 		if (yamon) {
 			if (strcmp(envname, *env++) == 0)
 				return *env;
-		} else {
-			if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
-				return *env + i + 1;
-		}
+		} else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
+			return *env + i + 1;
 		env++;
 	}
 
@@ -110,13 +107,13 @@
 {
 	int i;
 
-	for(i = 0; i < 6; i++) {
+	for (i = 0; i < 6; i++) {
 		unsigned char num;
 
-		if((*str == '.') || (*str == ':'))
+		if ((*str == '.') || (*str == ':'))
 			str++;
-		num = str2hexnum(*str++) << 4;
-		num |= (str2hexnum(*str++));
+		num  = str2hexnum(*str++) << 4;
+		num |= str2hexnum(*str++);
 		ea[i] = num;
 	}
 }
diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c
index e34c67e..55bbe24 100644
--- a/arch/mips/au1000/common/puts.c
+++ b/arch/mips/au1000/common/puts.c
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *	Low level uart routines to directly access a 16550 uart.
+ *	Low level UART routines to directly access Alchemy UART.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -40,12 +39,12 @@
 
 static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
 
-
 #ifdef SLOW_DOWN
 static inline void slow_down(void)
 {
-    int k;
-    for (k=0; k<10000; k++);
+	int k;
+
+	for (k = 0; k < 10000; k++);
 }
 #else
 #define slow_down()
@@ -54,16 +53,16 @@
 void
 prom_putchar(const unsigned char c)
 {
-    unsigned char ch;
-    int i = 0;
+	unsigned char ch;
+	int i = 0;
 
-    do {
-        ch = com1[SER_CMD];
-        slow_down();
-        i++;
-        if (i>TIMEOUT) {
-            break;
-        }
-    } while (0 == (ch & TX_BUSY));
-    com1[SER_DATA] = c;
+	do {
+		ch = com1[SER_CMD];
+		slow_down();
+		i++;
+		if (i > TIMEOUT)
+			break;
+	} while (0 == (ch & TX_BUSY));
+
+	com1[SER_DATA] = c;
 }
diff --git a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c
index 60cec53..d555429 100644
--- a/arch/mips/au1000/common/reset.c
+++ b/arch/mips/au1000/common/reset.c
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *	Au1000 reset routines.
+ *	Au1xx0 reset routines.
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2006, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -28,10 +27,11 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <asm/cacheflush.h>
+
 #include <asm/mach-au1x00/au1000.h>
 
 extern int au_sleep(void);
-extern void (*flush_cache_all)(void);
 
 void au1000_restart(char *command)
 {
@@ -40,8 +40,8 @@
 	u32 prid = read_c0_prid();
 
 	printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
-	switch (prid & 0xFF000000)
-	{
+
+	switch (prid & 0xFF000000) {
 	case 0x00000000: /* Au1000 */
 		au_writel(0x02, 0xb0000010); /* ac97_enable */
 		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
@@ -138,9 +138,6 @@
 		au_writel(0x00, 0xb1900064); /* sys_auxpll */
 		au_writel(0x00, 0xb1900100); /* sys_pininputen */
 		break;
-
-	default:
-		break;
 	}
 
 	set_c0_status(ST0_BEV | ST0_ERL);
@@ -158,25 +155,25 @@
 void au1000_halt(void)
 {
 #if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
-	/* power off system */
-	printk("\n** Powering off...\n");
-	au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
+	/* Power off system */
+	printk(KERN_NOTICE "\n** Powering off...\n");
+	au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C);
 	au_sync();
-	while(1); /* should not get here */
+	while (1); /* should not get here */
 #else
 	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
 #ifdef CONFIG_MIPS_MIRAGE
 	au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
 #endif
 #ifdef CONFIG_MIPS_DB1200
-	au_writew(au_readw(0xB980001C) | (1<<14), 0xB980001C);
+	au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
 #endif
 #ifdef CONFIG_PM
 	au_sleep();
 
-	/* should not get here */
-	printk(KERN_ERR "Unable to put cpu in sleep mode\n");
-	while(1);
+	/* Should not get here */
+	printk(KERN_ERR "Unable to put CPU in sleep mode\n");
+	while (1);
 #else
 	while (1)
 		__asm__(".set\tmips3\n\t"
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 0e86f7a..1ac6b06 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com
  *
  * Updates to 2.6, Pete Popov, Embedded Alley Solutions, Inc.
  *
@@ -48,7 +47,7 @@
 {
 	struct	cpu_spec *sp;
 	char *argptr;
-	unsigned long prid, cpufreq, bclk = 1;
+	unsigned long prid, cpufreq, bclk;
 
 	set_cpuspec();
 	sp = cur_cpu_spec[0];
@@ -66,42 +65,39 @@
 		cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12;
 	printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq);
 
-	bclk = sp->cpu_bclk;
-	if (bclk)
-	{
+	if (sp->cpu_bclk) {
 		/* Enable BCLK switching */
-		bclk = au_readl(0xB190003C);
-		au_writel(bclk | 0x60, 0xB190003C);
-		printk("BCLK switching enabled!\n");
+		bclk = au_readl(SYS_POWERCTRL);
+		au_writel(bclk | 0x60, SYS_POWERCTRL);
+		printk(KERN_INFO "BCLK switching enabled!\n");
 	}
 
-	if (sp->cpu_od) {
-		/* Various early Au1000 Errata corrected by this */
-		set_c0_config(1<<19); /* Set Config[OD] */
-	}
-	else {
+	if (sp->cpu_od)
+		/* Various early Au1xx0 errata corrected by this */
+		set_c0_config(1 << 19); /* Set Config[OD] */
+	else
 		/* Clear to obtain best system bus performance */
-		clear_c0_config(1<<19); /* Clear Config[OD] */
-	}
+		clear_c0_config(1 << 19); /* Clear Config[OD] */
 
 	argptr = prom_getcmdline();
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
-	if ((argptr = strstr(argptr, "console=")) == NULL) {
+	argptr = strstr(argptr, "console=");
+	if (argptr == NULL) {
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
 #endif
 
 #ifdef CONFIG_FB_AU1100
-    if ((argptr = strstr(argptr, "video=")) == NULL) {
-        argptr = prom_getcmdline();
-        /* default panel */
-        /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
-    }
+	argptr = strstr(argptr, "video=");
+	if (argptr == NULL) {
+		argptr = prom_getcmdline();
+		/* default panel */
+		/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
+	}
 #endif
 
-
 #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
 	/* au1000 does not support vra, au1500 and au1100 do */
 	strcat(argptr, " au1000_audio=vra");
@@ -129,7 +125,7 @@
 /* This routine should be valid for all Au1x based boards */
 phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
 {
-	/* Don't fixup 36 bit addresses */
+	/* Don't fixup 36-bit addresses */
 	if ((phys_addr >> 32) != 0)
 		return phys_addr;
 
@@ -145,17 +141,17 @@
 	}
 #endif
 
-	/* All Au1x SOCs have a pcmcia controller */
-	/* We setup our 32 bit pseudo addresses to be equal to the
-	 * 36 bit addr >> 4, to make it easier to check the address
+	/*
+	 * All Au1xx0 SOCs have a PCMCIA controller.
+	 * We setup our 32-bit pseudo addresses to be equal to the
+	 * 36-bit addr >> 4, to make it easier to check the address
 	 * and fix it.
-	 * The Au1x socket 0 phys attribute address is 0xF 4000 0000.
+	 * The PCMCIA socket 0 physical attribute address is 0xF 4000 0000.
 	 * The pseudo address we use is 0xF400 0000. Any address over
-	 * 0xF400 0000 is a pcmcia pseudo address.
+	 * 0xF400 0000 is a PCMCIA pseudo address.
 	 */
-	if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) {
+	if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF))
 		return (phys_t)(phys_addr << 4);
-	}
 
 	/* default nop */
 	return phys_addr;
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index bdb6d73..563d939 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -25,11 +25,9 @@
  *
  * Setting up the clock on the MIPS boards.
  *
- * Update.  Always configure the kernel with CONFIG_NEW_TIME_C.  This
- * will use the user interface gettimeofday() functions from the
- * arch/mips/kernel/time.c, and we provide the clock interrupt processing
- * and the timer offset compute functions.  If CONFIG_PM is selected,
- * we also ensure the 32KHz timer is available.   -- Dan
+ * We provide the clock interrupt processing and the timer offset compute
+ * functions.  If CONFIG_PM is selected, we also ensure the 32KHz timer is
+ * available.  -- Dan
  */
 
 #include <linux/types.h>
@@ -47,8 +45,7 @@
 #if HZ < 100 || HZ > 1000
 #error "unsupported HZ value! Must be in [100,1000]"
 #endif
-#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
-extern void startup_match20_interrupt(irq_handler_t handler);
+#define MATCH20_INC (328 * 100 / HZ) /* magic number 328 is for HZ=100... */
 static unsigned long last_pc0, last_match20;
 #endif
 
@@ -61,7 +58,7 @@
 {
 	unsigned long pc0;
 	int time_elapsed;
-	static int jiffie_drift = 0;
+	static int jiffie_drift;
 
 	if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
 		/* should never happen! */
@@ -70,13 +67,11 @@
 	}
 
 	pc0 = au_readl(SYS_TOYREAD);
-	if (pc0 < last_match20) {
+	if (pc0 < last_match20)
 		/* counter overflowed */
 		time_elapsed = (0xffffffff - last_match20) + pc0;
-	}
-	else {
+	else
 		time_elapsed = pc0 - last_match20;
-	}
 
 	while (time_elapsed > 0) {
 		do_timer(1);
@@ -92,8 +87,9 @@
 	au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
 	au_sync();
 
-	/* our counter ticks at 10.009765625 ms/tick, we we're running
-	 * almost 10uS too slow per tick.
+	/*
+	 * Our counter ticks at 10.009765625 ms/tick, we we're running
+	 * almost 10 uS too slow per tick.
 	 */
 
 	if (jiffie_drift >= 999) {
@@ -117,20 +113,17 @@
 /* When we wakeup from sleep, we have to "catch up" on all of the
  * timer ticks we have missed.
  */
-void
-wakeup_counter0_adjust(void)
+void wakeup_counter0_adjust(void)
 {
 	unsigned long pc0;
 	int time_elapsed;
 
 	pc0 = au_readl(SYS_TOYREAD);
-	if (pc0 < last_match20) {
+	if (pc0 < last_match20)
 		/* counter overflowed */
 		time_elapsed = (0xffffffff - last_match20) + pc0;
-	}
-	else {
+	else
 		time_elapsed = pc0 - last_match20;
-	}
 
 	while (time_elapsed > 0) {
 		time_elapsed -= MATCH20_INC;
@@ -143,10 +136,8 @@
 
 }
 
-/* This is just for debugging to set the timer for a sleep delay.
-*/
-void
-wakeup_counter0_set(int ticks)
+/* This is just for debugging to set the timer for a sleep delay. */
+void wakeup_counter0_set(int ticks)
 {
 	unsigned long pc0;
 
@@ -157,21 +148,22 @@
 }
 #endif
 
-/* I haven't found anyone that doesn't use a 12 MHz source clock,
+/*
+ * I haven't found anyone that doesn't use a 12 MHz source clock,
  * but just in case.....
  */
 #define AU1000_SRC_CLK	12000000
 
 /*
  * We read the real processor speed from the PLL.  This is important
- * because it is more accurate than computing it from the 32KHz
+ * because it is more accurate than computing it from the 32 KHz
  * counter, if it exists.  If we don't have an accurate processor
  * speed, all of the peripherals that derive their clocks based on
  * this advertised speed will introduce error and sometimes not work
  * properly.  This function is futher convoluted to still allow configurations
  * to do that in case they have really, really old silicon with a
- * write-only PLL register, that we need the 32KHz when power management
- * "wait" is enabled, and we need to detect if the 32KHz isn't present
+ * write-only PLL register, that we need the 32 KHz when power management
+ * "wait" is enabled, and we need to detect if the 32 KHz isn't present
  * but requested......got it? :-)		-- Dan
  */
 unsigned long calc_clock(void)
@@ -182,8 +174,7 @@
 
 	spin_lock_irqsave(&time_lock, flags);
 
-	/* Power management cares if we don't have a 32KHz counter.
-	*/
+	/* Power management cares if we don't have a 32 KHz counter. */
 	no_au1xxx_32khz = 0;
 	counter = au_readl(SYS_COUNTER_CNTRL);
 	if (counter & SYS_CNTRL_E0) {
@@ -193,7 +184,7 @@
 
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
 		/* RTC now ticks at 32.768/16 kHz */
-		au_writel(trim_divide-1, SYS_RTCTRIM);
+		au_writel(trim_divide - 1, SYS_RTCTRIM);
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
 
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
@@ -215,9 +206,11 @@
 #endif
 	else
 		cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
+	/* On Alchemy CPU:counter ratio is 1:1 */
 	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));
+	/* 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;
 }
@@ -228,10 +221,10 @@
 
 	est_freq += 5000;    /* round */
 	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
-	       (est_freq%1000000)*100/1000000);
- 	set_au1x00_speed(est_freq);
- 	set_au1x00_lcd_clock(); // program the LCD clock
+	printk(KERN_INFO "CPU frequency %u.%02u MHz\n",
+	       est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
+	set_au1x00_speed(est_freq);
+	set_au1x00_lcd_clock(); /* program the LCD clock */
 
 #ifdef CONFIG_PM
 	/*
@@ -243,30 +236,29 @@
 	 * counter 0 interrupt as a special irq and it doesn't show
 	 * up under /proc/interrupts.
 	 *
-	 * Check to ensure we really have a 32KHz oscillator before
+	 * Check to ensure we really have a 32 KHz oscillator before
 	 * we do this.
 	 */
 	if (no_au1xxx_32khz)
-		printk("WARNING: no 32KHz clock found.\n");
+		printk(KERN_WARNING "WARNING: no 32KHz clock found.\n");
 	else {
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
 		au_writel(0, SYS_TOYWRITE);
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
 
-		au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
+		au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK);
 		au_writel(~0, SYS_WAKESRC);
 		au_sync();
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
 
-		/* setup match20 to interrupt once every HZ */
+		/* Setup match20 to interrupt once every HZ */
 		last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
 		au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
 		au_sync();
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
 		setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
 
-		/* We can use the real 'wait' instruction.
-		*/
+		/* We can use the real 'wait' instruction. */
 		allow_au1k_wait = 1;
 	}
 
diff --git a/arch/mips/au1000/db1x00/Makefile b/arch/mips/au1000/db1x00/Makefile
index 51d62bd..274db3b 100644
--- a/arch/mips/au1000/db1x00/Makefile
+++ b/arch/mips/au1000/db1x00/Makefile
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
-# Makefile for the Alchemy Semiconductor Db1x00 board.
+# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
+#
 
 lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c
index b7dcbad..9e5ccbb 100644
--- a/arch/mips/au1000/db1x00/board_setup.c
+++ b/arch/mips/au1000/db1x00/board_setup.c
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *	Alchemy Db1x00 board setup.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -37,49 +36,49 @@
 
 void board_reset(void)
 {
-	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	/* Hit BCSR.SW_RESET[RESET] */
 	bcsr->swreset = 0x0000;
 }
 
 void __init board_setup(void)
 {
-	u32 pin_func;
+	u32 pin_func = 0;
 
-	pin_func = 0;
-	/* not valid for 1550 */
-
-#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
-	/* set IRFIRSEL instead of GPIO15 */
-	pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8));
+	/* Not valid for Au1550 */
+#if defined(CONFIG_IRDA) && \
+   (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
+	/* Set IRFIRSEL instead of GPIO15 */
+	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
 	au_writel(pin_func, SYS_PINFUNC);
-	/* power off until the driver is in use */
+	/* Power off until the driver is in use */
 	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
-	bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
+	bcsr->resets |=  BCSR_RESETS_IRDA_MODE_OFF;
 	au_sync();
 #endif
 	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
 
 #ifdef CONFIG_MIPS_MIRAGE
-	/* enable GPIO[31:0] inputs */
+	/* Enable GPIO[31:0] inputs */
 	au_writel(0, SYS_PININPUTEN);
 
-	/* GPIO[20] is output, tristate the other input primary GPIO's */
-	au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR);
+	/* GPIO[20] is output, tristate the other input primary GPIOs */
+	au_writel(~(1 << 20), SYS_TRIOUTCLR);
 
-	/* set GPIO[210:208] instead of SSI_0 */
-	pin_func = au_readl(SYS_PINFUNC) | (u32)(1);
+	/* Set GPIO[210:208] instead of SSI_0 */
+	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
 
-	/* set GPIO[215:211] for LED's */
-	pin_func |= (u32)((5<<2));
+	/* Set GPIO[215:211] for LEDs */
+	pin_func |= 5 << 2;
 
-	/* set GPIO[214:213] for more LED's */
-	pin_func |= (u32)((5<<12));
+	/* Set GPIO[214:213] for more LEDs */
+	pin_func |= 5 << 12;
 
-	/* set GPIO[207:200] instead of PCMCIA/LCD */
-	pin_func |= (u32)((3<<17));
+	/* Set GPIO[207:200] instead of PCMCIA/LCD */
+	pin_func |= SYS_PF_LCD | SYS_PF_PC;
 	au_writel(pin_func, SYS_PINFUNC);
 
-	/* Enable speaker amplifier.  This should
+	/*
+	 * Enable speaker amplifier.  This should
 	 * be part of the audio driver.
 	 */
 	au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
@@ -89,21 +88,21 @@
 	au_sync();
 
 #ifdef CONFIG_MIPS_DB1000
-    printk("AMD Alchemy Au1000/Db1000 Board\n");
+	printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1500
-    printk("AMD Alchemy Au1500/Db1500 Board\n");
+	printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1100
-    printk("AMD Alchemy Au1100/Db1100 Board\n");
+	printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
 #endif
 #ifdef CONFIG_MIPS_BOSPORUS
-    printk("AMD Alchemy Bosporus Board\n");
+	printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
 #endif
 #ifdef CONFIG_MIPS_MIRAGE
-    printk("AMD Alchemy Mirage Board\n");
+	printk(KERN_INFO "AMD Alchemy Mirage Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1550
-    printk("AMD Alchemy Au1550/Db1550 Board\n");
+	printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
 #endif
 }
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
index d3b967c..5ebe0de 100644
--- a/arch/mips/au1000/db1x00/init.c
+++ b/arch/mips/au1000/db1x00/init.c
@@ -2,9 +2,8 @@
  * BRIEF MODULE DESCRIPTION
  *	PB1000 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -49,8 +48,8 @@
 	unsigned long memsize;
 
 	prom_argc = fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
 
 	prom_init_cmdline();
 
@@ -58,6 +57,6 @@
 	if (!memsize_str)
 		memsize = 0x04000000;
 	else
-		memsize = simple_strtol(memsize_str, NULL, 0);
+		memsize = strict_strtol(memsize_str, 0, NULL);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
index eaa50c7..94c090e 100644
--- a/arch/mips/au1000/db1x00/irqmap.c
+++ b/arch/mips/au1000/db1x00/irqmap.c
@@ -32,32 +32,32 @@
 
 #ifdef CONFIG_MIPS_DB1500
 char irq_tab_alchemy[][5] __initdata = {
- [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT371   */
- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+	[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371   */
+	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
 };
 #endif
 
 #ifdef CONFIG_MIPS_BOSPORUS
 char irq_tab_alchemy[][5] __initdata = {
- [11] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 11 - miniPCI  */
- [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - SN1741   */
- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+	[11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI  */
+	[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741   */
+	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
 };
 #endif
 
 #ifdef CONFIG_MIPS_MIRAGE
 char irq_tab_alchemy[][5] __initdata = {
- [11] =	{ -1, INTD, INTX, INTX, INTX},   /* IDSEL 11 - SMI VGX */
- [12] =	{ -1, INTX, INTX, INTC, INTX},   /* IDSEL 12 - PNX1300 */
- [13] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 13 - miniPCI */
+	[11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */
+	[12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */
+	[13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */
 };
 #endif
 
 #ifdef CONFIG_MIPS_DB1550
 char irq_tab_alchemy[][5] __initdata = {
- [11] =	{ -1, INTC, INTX, INTX, INTX},   /* IDSEL 11 - on-board HPT371    */
- [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+	[11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */
+	[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
+	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
 };
 #endif
 
diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile
index 85a9094..7c67b3d 100644
--- a/arch/mips/au1000/mtx-1/Makefile
+++ b/arch/mips/au1000/mtx-1/Makefile
@@ -1,7 +1,6 @@
 #
 #  Copyright 2003 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #       Bruno Randolf <bruno.randolf@4g-systems.biz>
 #
 # Makefile for 4G Systems MTX-1 board.
diff --git a/arch/mips/au1000/mtx-1/board_setup.c b/arch/mips/au1000/mtx-1/board_setup.c
index 5736354..3f80791 100644
--- a/arch/mips/au1000/mtx-1/board_setup.c
+++ b/arch/mips/au1000/mtx-1/board_setup.c
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *	4G Systems MTX-1 board setup.
  *
- * Copyright 2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *         Bruno Randolf <bruno.randolf@4g-systems.biz>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -34,7 +33,7 @@
 #include <asm/mach-au1x00/au1000.h>
 
 extern int (*board_pci_idsel)(unsigned int devsel, int assert);
-int    mtx1_pci_idsel(unsigned int devsel, int assert);
+int mtx1_pci_idsel(unsigned int devsel, int assert);
 
 void board_reset(void)
 {
@@ -45,36 +44,36 @@
 void __init board_setup(void)
 {
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	// enable USB power switch
-	au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
-	au_writel( 0x100000, GPIO2_OUTPUT );
+	/* Enable USB power switch */
+	au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR);
+	au_writel(0x100000, GPIO2_OUTPUT);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
-	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
 #else
 	au_writel(0xf, Au1500_PCI_CFG);
 #endif
 #endif
 
-	// initialize sys_pinfunc:
-	au_writel( SYS_PF_NI2, SYS_PINFUNC );
+	/* Initialize sys_pinfunc */
+	au_writel(SYS_PF_NI2, SYS_PINFUNC);
 
-	// initialize GPIO
-	au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR );
-	au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF
-	au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF
-	au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
-	au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF
+	/* Initialize GPIO */
+	au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
+	au_writel(0x00000001, SYS_OUTPUTCLR); /* set M66EN (PCI 66MHz) to OFF */
+	au_writel(0x00000008, SYS_OUTPUTSET); /* set PCI CLKRUN# to OFF */
+	au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
+	au_writel(0x00000020, SYS_OUTPUTCLR); /* set eth PHY TX_ER to OFF */
 
-	// enable LED and set it to green
-	au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR );
-	au_writel( 0x18000800, GPIO2_OUTPUT );
+	/* Enable LED and set it to green */
+	au_writel(au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR);
+	au_writel(0x18000800, GPIO2_OUTPUT);
 
 	board_pci_idsel = mtx1_pci_idsel;
 
-	printk("4G Systems MTX-1 Board\n");
+	printk(KERN_INFO "4G Systems MTX-1 Board\n");
 }
 
 int
@@ -82,20 +81,18 @@
 {
 #define MTX_IDSEL_ONLY_0_AND_3 0
 #if MTX_IDSEL_ONLY_0_AND_3
-       if (devsel != 0 && devsel != 3) {
-               printk("*** not 0 or 3\n");
-               return 0;
-       }
+	if (devsel != 0 && devsel != 3) {
+		printk(KERN_ERR "*** not 0 or 3\n");
+		return 0;
+	}
 #endif
 
-       if (assert && devsel != 0) {
-               // suppress signal to cardbus
-               au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF
-       }
-       else {
-               au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
-       }
-       au_sync_udelay(1);
-       return 1;
+	if (assert && devsel != 0)
+		/* Suppress signal to Cardbus */
+		au_writel(0x00000002, SYS_OUTPUTCLR); /* set EXT_IO3 OFF */
+	else
+		au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
+	au_sync_udelay(1);
+	return 1;
 }
 
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index c015cbc..33a4aeb 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *	4G Systems MTX-1 board setup
  *
- * Copyright 2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *         Bruno Randolf <bruno.randolf@4g-systems.biz>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -47,8 +46,8 @@
 	unsigned long memsize;
 
 	prom_argc = fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
 
 	prom_init_cmdline();
 
@@ -56,6 +55,6 @@
 	if (!memsize_str)
 		memsize = 0x04000000;
 	else
-		memsize = simple_strtol(memsize_str, NULL, 0);
+		memsize = strict_strtol(memsize_str, 0, NULL);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
index 78d70c4..f2bf029 100644
--- a/arch/mips/au1000/mtx-1/irqmap.c
+++ b/arch/mips/au1000/mtx-1/irqmap.c
@@ -31,18 +31,18 @@
 #include <asm/mach-au1x00/au1000.h>
 
 char irq_tab_alchemy[][5] __initdata = {
- [0] = { -1, INTA, INTA, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
- [1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
- [2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
- [3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
- [4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
- [5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
- [6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
- [7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+	[0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */
+	[1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+	[2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */
+	[3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+	[4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */
+	[5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+	[6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */
+	[7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
 };
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
        { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
        { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c
index a7edbf0..9807be3 100644
--- a/arch/mips/au1000/mtx-1/platform.c
+++ b/arch/mips/au1000/mtx-1/platform.c
@@ -21,11 +21,10 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
+#include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 
-#include <asm/gpio.h>
-
 static struct gpio_keys_button mtx1_gpio_button[] = {
 	{
 		.gpio = 207,
diff --git a/arch/mips/au1000/pb1000/Makefile b/arch/mips/au1000/pb1000/Makefile
index daa1a50..99bbec0 100644
--- a/arch/mips/au1000/pb1000/Makefile
+++ b/arch/mips/au1000/pb1000/Makefile
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
-# Makefile for the Alchemy Semiconductor PB1000 board.
+# Makefile for the Alchemy Semiconductor Pb1000 board.
+#
 
 lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1000/board_setup.c b/arch/mips/au1000/pb1000/board_setup.c
index 33f15ac..25df167 100644
--- a/arch/mips/au1000/pb1000/board_setup.c
+++ b/arch/mips/au1000/pb1000/board_setup.c
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -40,128 +39,126 @@
 	u32 sys_freqctrl, sys_clksrc;
 	u32 prid = read_c0_prid();
 
-	// set AUX clock to 12MHz * 8 = 96 MHz
+	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
 	au_writel(0, SYS_PINSTATERD);
 	udelay(100);
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	/* zero and disable FREQ2 */
+	/* Zero and disable FREQ2 */
 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
-	/* zero and disable USBH/USBD clocks */
+	/* Zero and disable USBH/USBD clocks */
 	sys_clksrc = au_readl(SYS_CLKSRC);
-	sys_clksrc &= ~0x00007FE0;
+	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+		        SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
 	au_writel(sys_clksrc, SYS_CLKSRC);
 
 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 
 	sys_clksrc = au_readl(SYS_CLKSRC);
-	sys_clksrc &= ~0x00007FE0;
+	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+		        SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
 
-	switch (prid & 0x000000FF)
-	{
+	switch (prid & 0x000000FF) {
 	case 0x00: /* DA */
 	case 0x01: /* HA */
 	case 0x02: /* HB */
-	/* CPU core freq to 48MHz to slow it way down... */
-	au_writel(4, SYS_CPUPLL);
+		/* CPU core freq to 48 MHz to slow it way down... */
+		au_writel(4, SYS_CPUPLL);
 
-	/*
-	 * Setup 48MHz FREQ2 from CPUPLL for USB Host
-	 */
-	/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
-	sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
-	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+		/*
+		 * Setup 48 MHz FREQ2 from CPUPLL for USB Host
+		 * FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz
+		 */
+		sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2;
+		au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
-	/* CPU core freq to 384MHz */
-	au_writel(0x20, SYS_CPUPLL);
+		/* CPU core freq to 384 MHz */
+		au_writel(0x20, SYS_CPUPLL);
 
-	printk("Au1000: 48MHz OHCI workaround enabled\n");
+		printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n");
 		break;
 
-	default:  /* HC and newer */
-	// FREQ2 = aux/2 = 48 MHz
-	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+	default: /* HC and newer */
+		/* FREQ2 = aux / 2 = 48 MHz */
+		sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
+				 SYS_FC_FE2 | SYS_FC_FS2;
+		au_writel(sys_freqctrl, SYS_FREQCTRL0);
 		break;
 	}
 
 	/*
-	 * Route 48MHz FREQ2 into USB Host and/or Device
+	 * Route 48 MHz FREQ2 into USB Host and/or Device
 	 */
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
-#endif
+	sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
 	au_writel(sys_clksrc, SYS_CLKSRC);
 
-	// configure pins GPIO[14:9] as GPIO
-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
+	/* Configure pins GPIO[14:9] as GPIO */
+	pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB);
 
-	// 2nd USB port is USB host
-	pin_func |= 0x8000;
+	/* 2nd USB port is USB host */
+	pin_func |= SYS_PF_USB;
 
 	au_writel(pin_func, SYS_PINFUNC);
 	au_writel(0x2800, SYS_TRIOUTCLR);
 	au_writel(0x0030, SYS_OUTPUTCLR);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
-	// make gpio 15 an input (for interrupt line)
-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
-	// we don't need I2S, so make it available for GPIO[31:29]
-	pin_func |= (1<<5);
+	/* Make GPIO 15 an input (for interrupt line) */
+	pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF;
+	/* We don't need I2S, so make it available for GPIO[31:29] */
+	pin_func |= SYS_PF_I2S;
 	au_writel(pin_func, SYS_PINFUNC);
 
 	au_writel(0x8000, SYS_TRIOUTCLR);
 
-	static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
+	static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
 	au_writel(static_cfg0, MEM_STCFG0);
 
-	// configure RCE2* for LCD
+	/* configure RCE2* for LCD */
 	au_writel(0x00000004, MEM_STCFG2);
 
-	// MEM_STTIME2
+	/* MEM_STTIME2 */
 	au_writel(0x09000000, MEM_STTIME2);
 
-	// Set 32-bit base address decoding for RCE2*
+	/* Set 32-bit base address decoding for RCE2* */
 	au_writel(0x10003ff0, MEM_STADDR2);
 
-	// PCI CPLD setup
-	// expand CE0 to cover PCI
+	/*
+	 * PCI CPLD setup
+	 * Expand CE0 to cover PCI
+	 */
 	au_writel(0x11803e40, MEM_STADDR1);
 
-	// burst visibility on
+	/* Burst visibility on */
 	au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
 
-	au_writel(0x83, MEM_STCFG1);         // ewait enabled, flash timing
-	au_writel(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
+	au_writel(0x83, MEM_STCFG1);	     /* ewait enabled, flash timing */
+	au_writel(0x33030a10, MEM_STTIME1);  /* slower timing for FPGA */
 
-	/* setup the static bus controller */
+	/* Setup the static bus controller */
 	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
 	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
 	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
 
-#ifdef CONFIG_PCI
-	au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
-	au_writel(0, SDRAM_MBAR);        // set mbar to 0
-	au_writel(0x2, SDRAM_CMD);       // enable memory accesses
-	au_sync_delay(1);
-#endif
-
-	/* Enable Au1000 BCLK switching - note: sed1356 must not use
-	 * its BCLK (Au1000 LCLK) for any timings */
-	switch (prid & 0x000000FF)
-	{
+	/*
+	 * Enable Au1000 BCLK switching - note: sed1356 must not use
+	 * its BCLK (Au1000 LCLK) for any timings
+	 */
+	switch (prid & 0x000000FF) {
 	case 0x00: /* DA */
 	case 0x01: /* HA */
 	case 0x02: /* HB */
 		break;
 	default:  /* HC and newer */
-		/* Enable sys bus clock divider when IDLE state or no bus
-		   activity. */
+		/*
+		 * Enable sys bus clock divider when IDLE state or no bus
+		 * activity.
+		 */
 		au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
 		break;
 	}
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index 549447df7..3837365 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	PB1000 board setup
+ *	Pb1000 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -44,16 +43,15 @@
 	unsigned char *memsize_str;
 	unsigned long memsize;
 
-	prom_argc = (int) fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
+	prom_argc = (int)fw_arg0;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
-	if (!memsize_str) {
+	if (!memsize_str)
 		memsize = 0x04000000;
-	} else {
-		memsize = simple_strtol(memsize_str, NULL, 0);
-	}
+	else
+		memsize = strict_strtol(memsize_str, 0, NULL);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/pb1100/Makefile b/arch/mips/au1000/pb1100/Makefile
index 996236d..793e97c 100644
--- a/arch/mips/au1000/pb1100/Makefile
+++ b/arch/mips/au1000/pb1100/Makefile
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000,2001 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2001, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
 # Makefile for the Alchemy Semiconductor Pb1100 board.
+#
 
 lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1100/board_setup.c b/arch/mips/au1000/pb1100/board_setup.c
index 656164c..c0bfd59 100644
--- a/arch/mips/au1000/pb1100/board_setup.c
+++ b/arch/mips/au1000/pb1100/board_setup.c
@@ -1,7 +1,6 @@
 /*
- * Copyright 2002 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2002, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -32,15 +31,15 @@
 
 void board_reset(void)
 {
-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-    au_writel(0x00000000, 0xAE00001C);
+	/* Hit BCSR.RST_VDDI[SOFT_RESET] */
+	au_writel(0x00000000, PB1100_RST_VDDI);
 }
 
 void __init board_setup(void)
 {
-	volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL;
+	volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
 
-	// set AUX clock to 12MHz * 8 = 96 MHz
+	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
 	au_writel(0, SYS_PININPUTEN);
 	udelay(100);
@@ -49,44 +48,47 @@
 	{
 		u32 pin_func, sys_freqctrl, sys_clksrc;
 
-		// configure pins GPIO[14:9] as GPIO
-		pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+		/* Configure pins GPIO[14:9] as GPIO */
+		pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
 
-		/* zero and disable FREQ2 */
+		/* Zero and disable FREQ2 */
 		sys_freqctrl = au_readl(SYS_FREQCTRL0);
 		sys_freqctrl &= ~0xFFF00000;
 		au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
-		/* zero and disable USBH/USBD/IrDA clock */
+		/* Zero and disable USBH/USBD/IrDA clock */
 		sys_clksrc = au_readl(SYS_CLKSRC);
-		sys_clksrc &= ~0x0000001F;
+		sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
 		au_writel(sys_clksrc, SYS_CLKSRC);
 
 		sys_freqctrl = au_readl(SYS_FREQCTRL0);
 		sys_freqctrl &= ~0xFFF00000;
 
 		sys_clksrc = au_readl(SYS_CLKSRC);
-		sys_clksrc &= ~0x0000001F;
+		sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
 
-		// FREQ2 = aux/2 = 48 MHz
-		sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+		/* FREQ2 = aux / 2 = 48 MHz */
+		sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
+				SYS_FC_FE2 | SYS_FC_FS2;
 		au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 		/*
-		 * Route 48MHz FREQ2 into USBH/USBD/IrDA
+		 * Route 48 MHz FREQ2 into USBH/USBD/IrDA
 		 */
-		sys_clksrc |= ((4<<2) | (0<<1) | 0 );
+		sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT;
 		au_writel(sys_clksrc, SYS_CLKSRC);
 
-		/* setup the static bus controller */
+		/* Setup the static bus controller */
 		au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
 		au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
 		au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
 
-		// get USB Functionality pin state (device vs host drive pins)
-		pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-		// 2nd USB port is USB host
-		pin_func |= 0x8000;
+		/*
+		 * Get USB Functionality pin state (device vs host drive pins).
+		 */
+		pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
+		/* 2nd USB port is USB host. */
+		pin_func |= SYS_PF_USB;
 		au_writel(pin_func, SYS_PINFUNC);
 	}
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
@@ -94,12 +96,12 @@
 	/* Enable sys bus clock divider when IDLE state or no bus activity. */
 	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
 
-	// Enable the RTC if not already enabled
+	/* Enable the RTC if not already enabled. */
 	if (!(readb(base + 0x28) & 0x20)) {
 		writeb(readb(base + 0x28) | 0x20, base + 0x28);
 		au_sync();
 	}
-	// Put the clock in BCD mode
+	/* Put the clock in BCD mode. */
 	if (readb(base + 0x2C) & 0x4) { /* reg B */
 		writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
 		au_sync();
diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
index c913446..8355483 100644
--- a/arch/mips/au1000/pb1100/init.c
+++ b/arch/mips/au1000/pb1100/init.c
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *	Pb1100 board setup
  *
- * Copyright 2002 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2002, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -46,8 +45,8 @@
 	unsigned long memsize;
 
 	prom_argc = fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg3;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg3;
 
 	prom_init_cmdline();
 
@@ -55,7 +54,7 @@
 	if (!memsize_str)
 		memsize = 0x04000000;
 	else
-		memsize = simple_strtol(memsize_str, NULL, 0);
+		memsize = strict_strtol(memsize_str, 0, NULL);
 
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c
index b5021e3..9b7dd8b 100644
--- a/arch/mips/au1000/pb1100/irqmap.c
+++ b/arch/mips/au1000/pb1100/irqmap.c
@@ -1,6 +1,6 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Au1xxx irq map table
+ *	Au1xx0 IRQ map table
  *
  * Copyright 2003 Embedded Edge, LLC
  *		dan@embeddededge.com
@@ -31,10 +31,10 @@
 #include <asm/mach-au1x00/au1000.h>
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
-	{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
-	{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
-	{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ#
+	{ AU1000_GPIO_9,  INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */
+	{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */
+	{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */
+	{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */
 };
 
 int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile
index 4fe02ea..d678adf 100644
--- a/arch/mips/au1000/pb1200/Makefile
+++ b/arch/mips/au1000/pb1200/Makefile
@@ -1,5 +1,5 @@
 #
-# Makefile for the Alchemy Semiconductor PB1200 board.
+# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
 #
 
 lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
index 4493a79..6cb21150 100644
--- a/arch/mips/au1000/pb1200/board_setup.c
+++ b/arch/mips/au1000/pb1200/board_setup.c
@@ -27,16 +27,8 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 
-#include <au1000.h>
 #include <prom.h>
-
-#ifdef CONFIG_MIPS_PB1200
-#include <asm/mach-pb1x00/pb1200.h>
-#endif
-
-#ifdef CONFIG_MIPS_DB1200
-#include <asm/mach-db1x00/db1200.h>
-#endif
+#include <au1xxx.h>
 
 extern void _board_init_irq(void);
 extern void (*board_init_irq)(void);
@@ -53,56 +45,57 @@
 
 #if 0
 	{
-	u32 pin_func;
+		u32 pin_func;
 
-	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
-	 * but it is board specific code, so put it here.
-	 */
-	pin_func = au_readl(SYS_PINFUNC);
-	au_sync();
-	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
-	au_writel(pin_func, SYS_PINFUNC);
+		/*
+		 * Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
+		 * but it is board specific code, so put it here.
+		 */
+		pin_func = au_readl(SYS_PINFUNC);
+		au_sync();
+		pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+		au_writel(pin_func, SYS_PINFUNC);
 
-	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
-	au_sync();
+		au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
+		au_sync();
 	}
 #endif
 
 #if defined(CONFIG_I2C_AU1550)
 	{
-	u32 freq0, clksrc;
-	u32 pin_func;
+		u32 freq0, clksrc;
+		u32 pin_func;
 
-	/* Select SMBUS in CPLD */
-	bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);
+		/* Select SMBus in CPLD */
+		bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
 
-	pin_func = au_readl(SYS_PINFUNC);
-	au_sync();
-	pin_func &= ~(3<<17 | 1<<4);
-	/* Set GPIOs correctly */
-	pin_func |= 2<<17;
-	au_writel(pin_func, SYS_PINFUNC);
-	au_sync();
+		pin_func = au_readl(SYS_PINFUNC);
+		au_sync();
+		pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
+		/* Set GPIOs correctly */
+		pin_func |= 2 << 17;
+		au_writel(pin_func, SYS_PINFUNC);
+		au_sync();
 
-	/* The i2c driver depends on 50Mhz clock */
-	freq0 = au_readl(SYS_FREQCTRL0);
-	au_sync();
-	freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
-	freq0 |= (3<<SYS_FC_FRDIV1_BIT);
-	/* 396Mhz / (3+1)*2 == 49.5Mhz */
-	au_writel(freq0, SYS_FREQCTRL0);
-	au_sync();
-	freq0 |= SYS_FC_FE1;
-	au_writel(freq0, SYS_FREQCTRL0);
-	au_sync();
+		/* The I2C driver depends on 50 MHz clock */
+		freq0 = au_readl(SYS_FREQCTRL0);
+		au_sync();
+		freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
+		freq0 |= 3 << SYS_FC_FRDIV1_BIT;
+		/* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
+		au_writel(freq0, SYS_FREQCTRL0);
+		au_sync();
+		freq0 |= SYS_FC_FE1;
+		au_writel(freq0, SYS_FREQCTRL0);
+		au_sync();
 
-	clksrc = au_readl(SYS_CLKSRC);
-	au_sync();
-	clksrc &= ~0x01f00000;
-	/* bit 22 is EXTCLK0 for PSC0 */
-	clksrc |= (0x3 << 22);
-	au_writel(clksrc, SYS_CLKSRC);
-	au_sync();
+		clksrc = au_readl(SYS_CLKSRC);
+		au_sync();
+		clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
+		/* Bit 22 is EXTCLK0 for PSC0 */
+		clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
+		au_writel(clksrc, SYS_CLKSRC);
+		au_sync();
 	}
 #endif
 
@@ -116,27 +109,27 @@
 #endif
 #endif
 
-	/* The Pb1200 development board uses external MUX for PSC0 to
-	support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
-	*/
+	/*
+	 * The Pb1200 development board uses external MUX for PSC0 to
+	 * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
+	 */
 #ifdef CONFIG_I2C_AU1550
-	bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
+	bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
 #endif
 	au_sync();
 
 #ifdef CONFIG_MIPS_PB1200
-	printk("AMD Alchemy Pb1200 Board\n");
+	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
 #endif
 #ifdef CONFIG_MIPS_DB1200
-	printk("AMD Alchemy Db1200 Board\n");
+	printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
 #endif
 
 	/* Setup Pb1200 External Interrupt Controller */
 	board_init_irq = _board_init_irq;
 }
 
-int
-board_au1200fb_panel(void)
+int board_au1200fb_panel(void)
 {
 	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 	int p;
@@ -147,23 +140,23 @@
 	return p;
 }
 
-int
-board_au1200fb_panel_init(void)
+int board_au1200fb_panel_init(void)
 {
 	/* Apply power */
-    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-	bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
-	/*printk("board_au1200fb_panel_init()\n"); */
+	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+	bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL;
+	/* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
 	return 0;
 }
 
-int
-board_au1200fb_panel_shutdown(void)
+int board_au1200fb_panel_shutdown(void)
 {
 	/* Remove power */
-    BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
-	bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL);
-	/*printk("board_au1200fb_panel_shutdown()\n"); */
+	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+
+	bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+			 BCSR_BOARD_LCDBL);
+	/* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
 	return 0;
 }
-
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
index 72af550..09fd63b 100644
--- a/arch/mips/au1000/pb1200/init.c
+++ b/arch/mips/au1000/pb1200/init.c
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *	PB1200 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,16 +44,15 @@
 	unsigned char *memsize_str;
 	unsigned long memsize;
 
-	prom_argc = (int) fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
+	prom_argc = (int)fw_arg0;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
-	if (!memsize_str) {
+	if (!memsize_str)
 		memsize = 0x08000000;
-	} else {
-		memsize = simple_strtol(memsize_str, NULL, 0);
-	}
+	else
+		memsize = strict_strtol(memsize_str, 0, NULL);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
index e61eb8e..2a505ad 100644
--- a/arch/mips/au1000/pb1200/irqmap.c
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -39,25 +39,25 @@
 #endif
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade
+	/* This is external interrupt cascade */
+	{ AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 },
 };
 
 int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
 
 /*
- *	Support for External interrupts on the PbAu1200 Development platform.
+ * Support for External interrupts on the Pb1200 Development platform.
  */
-static volatile int pb1200_cascade_en=0;
+static volatile int pb1200_cascade_en;
 
-irqreturn_t pb1200_cascade_handler( int irq, void *dev_id)
+irqreturn_t pb1200_cascade_handler(int irq, void *dev_id)
 {
 	unsigned short bisr = bcsr->int_status;
 	int extirq_nr = 0;
 
-	/* Clear all the edge interrupts. This has no effect on level */
+	/* Clear all the edge interrupts. This has no effect on level. */
 	bcsr->int_status = bisr;
-	for( ; bisr; bisr &= (bisr-1) )
-	{
+	for ( ; bisr; bisr &= bisr - 1) {
 		extirq_nr = PB1200_INT_BEGIN + __ffs(bisr);
 		/* Ack and dispatch IRQ */
 		do_IRQ(extirq_nr);
@@ -68,26 +68,20 @@
 
 inline void pb1200_enable_irq(unsigned int irq_nr)
 {
-	bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
-	bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN);
+	bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+	bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
 }
 
 inline void pb1200_disable_irq(unsigned int irq_nr)
 {
-	bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN);
-	bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN);
+	bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+	bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
 }
 
 static unsigned int pb1200_setup_cascade(void)
 {
-	int err;
-
-	err = request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
-			  0, "Pb1200 Cascade", &pb1200_cascade_handler);
-	if (err)
-		return err;
-
-	return 0;
+	return request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
+			   0, "Pb1200 Cascade", &pb1200_cascade_handler);
 }
 
 static unsigned int pb1200_startup_irq(unsigned int irq)
@@ -132,23 +126,23 @@
 	unsigned int irq;
 
 #ifdef CONFIG_MIPS_PB1200
-	/* We have a problem with CPLD rev3. Enable a workaround */
+	/* We have a problem with CPLD rev 3. */
 	if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
-		printk("updated to latest revision. This software will not\n");
-		printk("work on anything less than CPLD rev4\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
-		printk("\nWARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
+		printk(KERN_ERR "updated to latest revision. This software will\n");
+		printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
+		printk(KERN_ERR "WARNING!!!\n");
 		panic("Game over.  Your score is 0.");
 	}
 #endif
@@ -161,6 +155,6 @@
 
 	/*
 	 * GPIO_7 can not be hooked here, so it is hooked upon first
-	 * request of any source attached to the cascade
+	 * request of any source attached to the cascade.
 	 */
 }
diff --git a/arch/mips/au1000/pb1500/Makefile b/arch/mips/au1000/pb1500/Makefile
index 97a7308..602f38d 100644
--- a/arch/mips/au1000/pb1500/Makefile
+++ b/arch/mips/au1000/pb1500/Makefile
@@ -1,8 +1,8 @@
 #
-#  Copyright 2000,2001 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2001, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
 # Makefile for the Alchemy Semiconductor Pb1500 board.
+#
 
 lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1500/board_setup.c b/arch/mips/au1000/pb1500/board_setup.c
index 24c652e..035771c 100644
--- a/arch/mips/au1000/pb1500/board_setup.c
+++ b/arch/mips/au1000/pb1500/board_setup.c
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -32,8 +31,8 @@
 
 void board_reset(void)
 {
-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-    au_writel(0x00000000, 0xAE00001C);
+	/* Hit BCSR.RST_VDDI[SOFT_RESET] */
+	au_writel(0x00000000, PB1500_RST_VDDI);
 }
 
 void __init board_setup(void)
@@ -42,7 +41,7 @@
 	u32 sys_freqctrl, sys_clksrc;
 
 	sys_clksrc = sys_freqctrl = pin_func = 0;
-	// set AUX clock to 12MHz * 8 = 96 MHz
+	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
 	au_writel(0, SYS_PINSTATERD);
 	udelay(100);
@@ -51,51 +50,48 @@
 
 	/* GPIO201 is input for PCMCIA card detect */
 	/* GPIO203 is input for PCMCIA interrupt request */
-	au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);
+	au_writel(au_readl(GPIO2_DIR) & ~((1 << 1) | (1 << 3)), GPIO2_DIR);
 
-	/* zero and disable FREQ2 */
+	/* Zero and disable FREQ2 */
 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/* zero and disable USBH/USBD clocks */
 	sys_clksrc = au_readl(SYS_CLKSRC);
-	sys_clksrc &= ~0x00007FE0;
+	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
 	au_writel(sys_clksrc, SYS_CLKSRC);
 
 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 
 	sys_clksrc = au_readl(SYS_CLKSRC);
-	sys_clksrc &= ~0x00007FE0;
+	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
 
-	// FREQ2 = aux/2 = 48 MHz
-	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	/* FREQ2 = aux/2 = 48 MHz */
+	sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2;
 	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/*
 	 * Route 48MHz FREQ2 into USB Host and/or Device
 	 */
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
-#endif
+	sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
 	au_writel(sys_clksrc, SYS_CLKSRC);
 
-
-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-	// 2nd USB port is USB host
-	pin_func |= 0x8000;
+	pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
+	/* 2nd USB port is USB host */
+	pin_func |= SYS_PF_USB;
 	au_writel(pin_func, SYS_PINFUNC);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
-
-
 #ifdef CONFIG_PCI
-	// Setup PCI bus controller
+	/* Setup PCI bus controller */
 	au_writel(0, Au1500_PCI_CMEM);
 	au_writel(0x00003fff, Au1500_CFG_BASE);
 #if defined(__MIPSEB__)
-	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
 #else
 	au_writel(0xf, Au1500_PCI_CFG);
 #endif
@@ -112,11 +108,11 @@
 
 	/* Enable the RTC if not already enabled */
 	if (!(au_readl(0xac000028) & 0x20)) {
-		printk("enabling clock ...\n");
+		printk(KERN_INFO "enabling clock ...\n");
 		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
 	}
 	/* Put the clock in BCD mode */
-	if (au_readl(0xac00002C) & 0x4) { /* reg B */
+	if (au_readl(0xac00002c) & 0x4) { /* reg B */
 		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
 		au_sync();
 	}
diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
index 488507c..49f51e1 100644
--- a/arch/mips/au1000/pb1500/init.c
+++ b/arch/mips/au1000/pb1500/init.c
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *	PB1500 board setup
+ *	Pb1500 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,16 +44,15 @@
 	unsigned char *memsize_str;
 	unsigned long memsize;
 
-	prom_argc = (int) fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
+	prom_argc = (int)fw_arg0;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
-	if (!memsize_str) {
+	if (!memsize_str)
 		memsize = 0x04000000;
-	} else {
-		memsize = simple_strtol(memsize_str, NULL, 0);
-	}
+	else
+		memsize = strict_strtol(memsize_str, 0, NULL);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
index 4817ab4..39c4682 100644
--- a/arch/mips/au1000/pb1500/irqmap.c
+++ b/arch/mips/au1000/pb1500/irqmap.c
@@ -31,12 +31,12 @@
 #include <asm/mach-au1x00/au1000.h>
 
 char irq_tab_alchemy[][5] __initdata = {
- [12] = { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT370   */
- [13] = { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+	[12] = { -1, INTA, INTX, INTX, INTX },   /* IDSEL 12 - HPT370	*/
+	[13] = { -1, INTA, INTB, INTC, INTD },   /* IDSEL 13 - PCI slot */
 };
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/pb1550/Makefile b/arch/mips/au1000/pb1550/Makefile
index aa35bc6..7d8beca 100644
--- a/arch/mips/au1000/pb1550/Makefile
+++ b/arch/mips/au1000/pb1550/Makefile
@@ -1,9 +1,8 @@
 #
-#  Copyright 2000 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Copyright 2000, 2008 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
-# Makefile for the Alchemy Semiconductor PB1000 board.
+# Makefile for the Alchemy Semiconductor Pb1550 board.
 #
 
 lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1550/board_setup.c b/arch/mips/au1000/pb1550/board_setup.c
index 45d6087..0ed76b6 100644
--- a/arch/mips/au1000/pb1550/board_setup.c
+++ b/arch/mips/au1000/pb1550/board_setup.c
@@ -3,9 +3,8 @@
  * BRIEF MODULE DESCRIPTION
  *	Alchemy Pb1550 board setup.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -35,15 +34,16 @@
 
 void board_reset(void)
 {
-    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-	au_writew(au_readw(0xAF00001C) & ~(1<<15), 0xAF00001C);
+	/* Hit BCSR.SYSTEM[RESET] */
+	au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
 }
 
 void __init board_setup(void)
 {
 	u32 pin_func;
 
-	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
+	/*
+	 * Enable PSC1 SYNC for AC'97.  Normaly done in audio driver,
 	 * but it is board specific code, so put it here.
 	 */
 	pin_func = au_readl(SYS_PINFUNC);
@@ -51,8 +51,8 @@
 	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
 	au_writel(pin_func, SYS_PINFUNC);
 
-	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
+	au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
 	au_sync();
 
-	printk("AMD Alchemy Pb1550 Board\n");
+	printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
 }
diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
index f6b2fc5..1b5f584 100644
--- a/arch/mips/au1000/pb1550/init.c
+++ b/arch/mips/au1000/pb1550/init.c
@@ -1,11 +1,10 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *	PB1550 board setup
+ *	Pb1550 board setup
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,16 +44,15 @@
 	unsigned char *memsize_str;
 	unsigned long memsize;
 
-	prom_argc = (int) fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
+	prom_argc = (int)fw_arg0;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
-	if (!memsize_str) {
+	if (!memsize_str)
 		memsize = 0x08000000;
-	} else {
-		memsize = simple_strtol(memsize_str, NULL, 0);
-	}
+	else
+		memsize = strict_strtol(memsize_str, 0, NULL);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
index e1dac37..a02a4d1 100644
--- a/arch/mips/au1000/pb1550/irqmap.c
+++ b/arch/mips/au1000/pb1550/irqmap.c
@@ -1,6 +1,6 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Au1xxx irq map table
+ *	Au1xx0 IRQ map table
  *
  * Copyright 2003 Embedded Edge, LLC
  *		dan@embeddededge.com
@@ -31,8 +31,8 @@
 #include <asm/mach-au1x00/au1000.h>
 
 char irq_tab_alchemy[][5] __initdata = {
- [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
- [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+	[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left)  */
+	[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
 };
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
diff --git a/arch/mips/au1000/xxs1500/Makefile b/arch/mips/au1000/xxs1500/Makefile
index 44d7f70..db3c526 100644
--- a/arch/mips/au1000/xxs1500/Makefile
+++ b/arch/mips/au1000/xxs1500/Makefile
@@ -1,7 +1,6 @@
 #
 #  Copyright 2003 MontaVista Software Inc.
-#  Author: MontaVista Software, Inc.
-#     	ppopov@mvista.com or source@mvista.com
+#  Author: MontaVista Software, Inc. <source@mvista.com>
 #
 # Makefile for MyCable XXS1500 board.
 #
diff --git a/arch/mips/au1000/xxs1500/board_setup.c b/arch/mips/au1000/xxs1500/board_setup.c
index 79d1798..4c587ac 100644
--- a/arch/mips/au1000/xxs1500/board_setup.c
+++ b/arch/mips/au1000/xxs1500/board_setup.c
@@ -1,7 +1,6 @@
 /*
- * Copyright 2000-2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2000-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -39,40 +38,40 @@
 {
 	u32 pin_func;
 
-	// set multiple use pins (UART3/GPIO) to UART (it's used as UART too)
-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~SYS_PF_UR3);
+	/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
+	pin_func  = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
 	pin_func |= SYS_PF_UR3;
 	au_writel(pin_func, SYS_PINFUNC);
 
-	// enable UART
-	au_writel(0x01, UART3_ADDR+UART_MOD_CNTRL); // clock enable (CE)
+	/* Enable UART */
+	au_writel(0x01, UART3_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
 	mdelay(10);
-	au_writel(0x03, UART3_ADDR+UART_MOD_CNTRL); // CE and "enable"
+	au_writel(0x03, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
 	mdelay(10);
 
-	// enable DTR = USB power up
-	au_writel(0x01, UART3_ADDR+UART_MCR); //? UART_MCR_DTR is 0x01???
+	/* Enable DTR = USB power up */
+	au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
 
 #ifdef CONFIG_PCMCIA_XXS1500
-	/* setup pcmcia signals */
+	/* Setup PCMCIA signals */
 	au_writel(0, SYS_PININPUTEN);
 
-	/* gpio 0, 1, and 4 are inputs */
-	au_writel(1 | (1<<1) | (1<<4), SYS_TRIOUTCLR);
+	/* GPIO 0, 1, and 4 are inputs */
+	au_writel(1 | (1 << 1) | (1 << 4), SYS_TRIOUTCLR);
 
-	/* enable GPIO2 if not already enabled */
+	/* Enable GPIO2 if not already enabled */
 	au_writel(1, GPIO2_ENABLE);
-	/* gpio2 208/9/10/11 are inputs */
-	au_writel((1<<8) | (1<<9) | (1<<10) | (1<<11), GPIO2_DIR);
+	/* GPIO2 208/9/10/11 are inputs */
+	au_writel((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11), GPIO2_DIR);
 
-	/* turn off power */
-	au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), GPIO2_OUTPUT);
+	/* Turn off power */
+	au_writel((au_readl(GPIO2_PINSTATE) & ~(1 << 14)) | (1 << 30),
+		  GPIO2_OUTPUT);
 #endif
 
-
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
-	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
 #else
 	au_writel(0xf, Au1500_PCI_CFG);
 #endif
diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
index 24fc6e1..b849bf5 100644
--- a/arch/mips/au1000/xxs1500/init.c
+++ b/arch/mips/au1000/xxs1500/init.c
@@ -2,9 +2,8 @@
  * BRIEF MODULE DESCRIPTION
  *	XXS1500 board setup
  *
- * Copyright 2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -45,8 +44,8 @@
 	unsigned long memsize;
 
 	prom_argc = fw_arg0;
-	prom_argv = (char **) fw_arg1;
-	prom_envp = (char **) fw_arg2;
+	prom_argv = (char **)fw_arg1;
+	prom_envp = (char **)fw_arg2;
 
 	prom_init_cmdline();
 
@@ -54,6 +53,6 @@
 	if (!memsize_str)
 		memsize = 0x04000000;
 	else
-		memsize = simple_strtol(memsize_str, NULL, 0);
+		memsize = strict_strtol(memsize_str, 0, NULL);
 	add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c
index dd6e3d1..edf06ed 100644
--- a/arch/mips/au1000/xxs1500/irqmap.c
+++ b/arch/mips/au1000/xxs1500/irqmap.c
@@ -31,7 +31,7 @@
 #include <asm/mach-au1x00/au1000.h>
 
 struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
-	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c
index 82f9e901..62bfb45 100644
--- a/arch/mips/emma2rh/markeins/setup.c
+++ b/arch/mips/emma2rh/markeins/setup.c
@@ -76,7 +76,9 @@
 	while (1) ;
 }
 
-static unsigned long clock[4] = { 166500000, 187312500, 199800000, 210600000 };
+static unsigned long __initdata emma2rh_clock[4] = {
+	166500000, 187312500, 199800000, 210600000
+};
 
 static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
 {
@@ -85,7 +87,8 @@
 	/* detect from boot strap */
 	reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0);
 	reg = (reg >> 4) & 0x3;
-	return clock[reg];
+
+	return emma2rh_clock[reg];
 }
 
 void __init plat_time_init(void)
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 45545be..cc02440 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -56,9 +56,9 @@
 obj-$(CONFIG_MIPS_CMP)		+= smp-cmp.o
 obj-$(CONFIG_CPU_MIPSR2)	+= spram.o
 
-obj-$(CONFIG_MIPS_APSP_KSPD)	+= kspd.o
 obj-$(CONFIG_MIPS_VPE_LOADER)	+= vpe.o
 obj-$(CONFIG_MIPS_VPE_APSP_API)	+= rtlx.o
+obj-$(CONFIG_MIPS_APSP_KSPD)	+= kspd.o
 
 obj-$(CONFIG_I8259)		+= i8259.o
 obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index a1b48af..02b7713 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -38,7 +38,7 @@
 		".endr\n\t"
 		".set	pop"
 		:
-		: GCC_IMM_ASM(align), GCC_IMM_ASM(mod));
+		: GCC_IMM_ASM() (align), GCC_IMM_ASM() (mod));
 }
 
 static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 290d8e3..469c723 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -578,7 +578,7 @@
  * process and the system, here we map the page and fill the
  * structure
  */
-static void irix_map_prda_page(void)
+static int irix_map_prda_page(void)
 {
 	unsigned long v;
 	struct prda *pp;
@@ -587,8 +587,8 @@
 	v =  do_brk(PRDA_ADDRESS, PAGE_SIZE);
 	up_write(&current->mm->mmap_sem);
 
-	if (v < 0)
-		return;
+	if (v != PRDA_ADDRESS)
+		return v;		/* v must be an error code */
 
 	pp = (struct prda *) v;
 	pp->prda_sys.t_pid  = task_pid_vnr(current);
@@ -596,6 +596,8 @@
 	pp->prda_sys.t_rpid = task_pid_vnr(current);
 
 	/* We leave the rest set to zero */
+
+	return 0;
 }
 
 
@@ -781,7 +783,8 @@
 	 * IRIX maps a page at 0x200000 which holds some system
 	 * information.  Programs depend on this.
 	 */
-	irix_map_prda_page();
+	if (irix_map_prda_page())
+		goto out_free_dentry;
 
 	padzero(elf_bss);
 
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index ceb62dc..b0591ae 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -257,7 +257,7 @@
 
 		vcwd = vpe_getcwd(tclimit);
 
- 		/* change to the cwd of the process that loaded the SP program */
+		/* change to cwd of the process that loaded the SP program */
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
 		sys_chdir(vcwd);
@@ -323,6 +323,9 @@
 			set >>= 1;
 		}
 	}
+
+	/* Put daemon cwd back to root to avoid umount problems */
+	sys_chdir("/");
 }
 
 static int channel_open = 0;
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 0233798..b88f1c1 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -72,6 +72,15 @@
 static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
 {
 	int i;
+	unsigned int flags, vpeflags;
+
+	/* Ought not to be strictly necessary for SMTC builds */
+	local_irq_save(flags);
+	vpeflags = dvpe();
+	set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
+	irq_enable_hazard();
+	evpe(vpeflags);
+	local_irq_restore(flags);
 
 	for (i = 0; i < RTLX_CHANNELS; i++) {
 			wake_up(&channel_wqs[i].lx_queue);
@@ -108,7 +117,8 @@
 static int rtlx_init(struct rtlx_info *rtlxi)
 {
 	if (rtlxi->id != RTLX_ID) {
-		printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id);
+		printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n",
+			rtlxi, rtlxi->id);
 		return -ENOEXEC;
 	}
 
@@ -162,18 +172,17 @@
 
 	if (rtlx == NULL) {
 		if( (p = vpe_get_shared(tclimit)) == NULL) {
-			if (can_sleep) {
-				__wait_event_interruptible(channel_wqs[index].lx_queue,
-				                           (p = vpe_get_shared(tclimit)),
-				                           ret);
-				if (ret)
-					goto out_fail;
-			} else {
-				printk(KERN_DEBUG "No SP program loaded, and device "
-					"opened with O_NONBLOCK\n");
-				ret = -ENOSYS;
+		    if (can_sleep) {
+			__wait_event_interruptible(channel_wqs[index].lx_queue,
+				(p = vpe_get_shared(tclimit)), ret);
+			if (ret)
 				goto out_fail;
-			}
+		    } else {
+			printk(KERN_DEBUG "No SP program loaded, and device "
+					"opened with O_NONBLOCK\n");
+			ret = -ENOSYS;
+			goto out_fail;
+		    }
 		}
 
 		smp_rmb();
@@ -182,7 +191,9 @@
 				DEFINE_WAIT(wait);
 
 				for (;;) {
-					prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE);
+					prepare_to_wait(
+						&channel_wqs[index].lx_queue,
+						&wait, TASK_INTERRUPTIBLE);
 					smp_rmb();
 					if (*p != NULL)
 						break;
@@ -195,7 +206,7 @@
 				}
 				finish_wait(&channel_wqs[index].lx_queue, &wait);
 			} else {
-				printk(" *vpe_get_shared is NULL. "
+				pr_err(" *vpe_get_shared is NULL. "
 				       "Has an SP program been loaded?\n");
 				ret = -ENOSYS;
 				goto out_fail;
@@ -203,8 +214,9 @@
 		}
 
 		if ((unsigned int)*p < KSEG0) {
-			printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
-			       "maybe an error code %d\n", (int)*p);
+			printk(KERN_WARNING "vpe_get_shared returned an "
+			       "invalid pointer maybe an error code %d\n",
+			       (int)*p);
 			ret = -ENOSYS;
 			goto out_fail;
 		}
@@ -232,6 +244,10 @@
 
 int rtlx_release(int index)
 {
+	if (rtlx == NULL) {
+		pr_err("rtlx_release() with null rtlx\n");
+		return 0;
+	}
 	rtlx->channel[index].lx_state = RTLX_STATE_UNUSED;
 	return 0;
 }
@@ -251,8 +267,8 @@
 			int ret = 0;
 
 			__wait_event_interruptible(channel_wqs[index].lx_queue,
-			                           chan->lx_read != chan->lx_write || sp_stopping,
-			                           ret);
+				(chan->lx_read != chan->lx_write) ||
+				sp_stopping, ret);
 			if (ret)
 				return ret;
 
@@ -282,7 +298,9 @@
 unsigned int rtlx_write_poll(int index)
 {
 	struct rtlx_channel *chan = &rtlx->channel[index];
-	return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
+
+	return write_spacefree(chan->rt_read, chan->rt_write,
+				chan->buffer_size);
 }
 
 ssize_t rtlx_read(int index, void __user *buff, size_t count)
@@ -344,8 +362,8 @@
 	rt_read = rt->rt_read;
 
 	/* total number of bytes to copy */
-	count = min(count,
-		    (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size));
+	count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write,
+							rt->buffer_size));
 
 	/* first bit from write pointer to the end of the buffer, or count */
 	fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
@@ -514,6 +532,11 @@
 
 	if (cpu_has_vint)
 		set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
+	else {
+		pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
+		err = -ENODEV;
+		goto out_chrdev;
+	}
 
 	rtlx_irq.dev_id = rtlx;
 	setup_irq(rtlx_irq_num, &rtlx_irq);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 39f3dfe..c6a063b 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -331,6 +331,7 @@
 	/*
 	 * Determine low and high memory ranges
 	 */
+	max_pfn = max_low_pfn;
 	if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
 #ifdef CONFIG_HIGHMEM
 		highstart_pfn = PFN_DOWN(HIGHMEM_START);
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 33780cc..63370cd 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -87,8 +87,8 @@
 
 __cpuinit void register_smp_ops(struct plat_smp_ops *ops)
 {
-	if (ops)
-		printk(KERN_WARNING "Overriding previous set SMP ops\n");
+	if (mp_ops)
+		printk(KERN_WARNING "Overriding previously set SMP ops\n");
 
 	mp_ops = ops;
 }
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 39804c5..2794501 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -269,7 +269,7 @@
 	 * This means you must tell Linux to use less memory than you
 	 * physically have, for example by passing a mem= boot argument.
 	 */
-	addr = pfn_to_kaddr(max_pfn);
+	addr = pfn_to_kaddr(max_low_pfn);
 	memset(addr, 0, len);
 #else
 	/* simple grab some mem for now */
@@ -781,10 +781,15 @@
 	/* take system out of configuration state */
 	clear_c0_mvpcontrol(MVPCONTROL_VPC);
 
+	/*
+	 * SMTC/SMVP kernels manage VPE enable independently,
+	 * but uniprocessor kernels need to turn it on, even
+	 * if that wasn't the pre-dvpe() state.
+	 */
 #ifdef CONFIG_SMP
-	evpe(EVPE_ENABLE);
-#else
 	evpe(vpeflags);
+#else
+	evpe(EVPE_ENABLE);
 #endif
 	emt(dmt_flag);
 	local_irq_restore(flags);
@@ -840,7 +845,7 @@
 
 	/* Sanity checks against insmoding binaries or wrong arch,
 	   weird elf version */
-	if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
+	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
 	    || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
 	    || !elf_check_arch(hdr)
 	    || hdr->e_shentsize != sizeof(*sechdrs)) {
@@ -947,12 +952,14 @@
 		struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
 
 		for (i = 0; i < hdr->e_phnum; i++) {
-			if (phdr->p_type != PT_LOAD)
-				continue;
-
-			memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
-			memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
-			phdr++;
+			if (phdr->p_type == PT_LOAD) {
+				memcpy((void *)phdr->p_paddr,
+				       (char *)hdr + phdr->p_offset,
+				       phdr->p_filesz);
+				memset((void *)phdr->p_paddr + phdr->p_filesz,
+				       0, phdr->p_memsz - phdr->p_filesz);
+		    }
+		    phdr++;
 		}
 
 		for (i = 0; i < hdr->e_shnum; i++) {
@@ -1107,7 +1114,7 @@
 		return -ENODEV;
 
 	hdr = (Elf_Ehdr *) v->pbuffer;
-	if (memcmp(hdr->e_ident, ELFMAG, 4) == 0) {
+	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
 		if (vpe_elfload(v) >= 0) {
 			vpe_run(v);
 		} else {
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 10dd2af..8f2cd8e 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -116,4 +116,3 @@
 EXPORT_SYMBOL(__kunmap);
 EXPORT_SYMBOL(__kmap_atomic);
 EXPORT_SYMBOL(__kunmap_atomic);
-EXPORT_SYMBOL(__kmap_atomic_to_page);
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index da8cbb6..b40df7d 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -281,7 +281,7 @@
 
 static void reset_counters(void *arg)
 {
-	int counters = (int)arg;
+	int counters = (int)(long)arg;
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(0);
@@ -313,7 +313,7 @@
 	if (!cpu_has_mipsmt_pertccounters)
 		counters = counters_total_to_per_cpu(counters);
 #endif
-	on_each_cpu(reset_counters, (void *)counters, 0, 1);
+	on_each_cpu(reset_counters, (void *)(long)counters, 0, 1);
 
 	op_model_mipsxx_ops.num_counters = counters;
 	switch (current_cpu_type()) {
@@ -382,7 +382,7 @@
 	int counters = op_model_mipsxx_ops.num_counters;
 
 	counters = counters_per_cpu_to_total(counters);
-	on_each_cpu(reset_counters, (void *)counters, 0, 1);
+	on_each_cpu(reset_counters, (void *)(long)counters, 0, 1);
 
 	perf_irq = save_perf_irq;
 }
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
index 00c36c9..e2ddfc4 100644
--- a/arch/mips/pci/fixup-au1000.c
+++ b/arch/mips/pci/fixup-au1000.c
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Board specific pci fixups.
+ *	Board specific PCI fixups.
  *
- * Copyright 2001-2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
index 1314bd5..9a57c5a 100644
--- a/arch/mips/pci/ops-au1000.c
+++ b/arch/mips/pci/ops-au1000.c
@@ -1,10 +1,9 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Alchemy/AMD Au1x00 PCI support.
+ *	Alchemy/AMD Au1xx0 PCI support.
  *
- * Copyright 2001-2003, 2007 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  *  Support for all devices (greater than 16) added by David Gathright.
  *
@@ -28,6 +27,7 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -36,9 +36,9 @@
 
 #include <asm/mach-au1x00/au1000.h>
 
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(x...) printk(x)
+#undef	DEBUG
+#ifdef	DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
 #else
 #define DBG(x...)
 #endif
@@ -46,7 +46,6 @@
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
-
 int (*board_pci_idsel)(unsigned int devsel, int assert);
 
 void mod_wired_entry(int entry, unsigned long entrylo0,
@@ -92,10 +91,9 @@
 }
 
 static int config_access(unsigned char access_type, struct pci_bus *bus,
-			 unsigned int dev_fn, unsigned char where,
-			 u32 * data)
+			 unsigned int dev_fn, unsigned char where, u32 *data)
 {
-#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
 	unsigned int device = PCI_SLOT(dev_fn);
 	unsigned int function = PCI_FUNC(dev_fn);
 	unsigned long offset, status;
@@ -114,38 +112,36 @@
 			Au1500_PCI_STATCMD);
 	au_sync_udelay(1);
 
-	/* Allow board vendors to implement their own off-chip idsel.
+	/*
+	 * Allow board vendors to implement their own off-chip IDSEL.
 	 * If it doesn't succeed, may as well bail out at this point.
 	 */
-	if (board_pci_idsel) {
-		if (board_pci_idsel(device, 1) == 0) {
-			*data = 0xffffffff;
-			local_irq_restore(flags);
-			return -1;
-		}
+	if (board_pci_idsel && board_pci_idsel(device, 1) == 0) {
+		*data = 0xffffffff;
+		local_irq_restore(flags);
+		return -1;
 	}
 
-        /* setup the config window */
-        if (bus->number == 0) {
-                cfg_base = ((1<<device)<<11);
-        } else {
-                cfg_base = 0x80000000 | (bus->number<<16) | (device<<11);
-        }
+	/* Setup the config window */
+	if (bus->number == 0)
+		cfg_base = (1 << device) << 11;
+	else
+		cfg_base = 0x80000000 | (bus->number << 16) | (device << 11);
 
-        /* setup the lower bits of the 36 bit address */
-        offset = (function << 8) | (where & ~0x3);
-	/* pick up any address that falls below the page mask */
+	/* Setup the lower bits of the 36-bit address */
+	offset = (function << 8) | (where & ~0x3);
+	/* Pick up any address that falls below the page mask */
 	offset |= cfg_base & ~PAGE_MASK;
 
-	/* page boundary */
+	/* Page boundary */
 	cfg_base = cfg_base & PAGE_MASK;
 
 	/*
 	 * To improve performance, if the current device is the same as
 	 * the last device accessed, we don't touch the TLB.
 	 */
-	entryLo0 = (6 << 26)  | (cfg_base >> 6) | (2 << 3) | 7;
-	entryLo1 = (6 << 26)  | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
+	entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
+	entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
 	if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
 		mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
 				(unsigned long)pci_cfg_vm->addr, PM_4K);
@@ -153,38 +149,37 @@
 		last_entryLo1 = entryLo1;
 	}
 
-	if (access_type == PCI_ACCESS_WRITE) {
+	if (access_type == PCI_ACCESS_WRITE)
 		au_writel(*data, (int)(pci_cfg_vm->addr + offset));
-	} else {
+	else
 		*data = au_readl((int)(pci_cfg_vm->addr + offset));
-	}
+
 	au_sync_udelay(2);
 
-	DBG("cfg_access %d bus->number %d dev %d at %x *data %x conf %x\n",
-			access_type, bus->number, device, where, *data, offset);
+	DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n",
+	    access_type, bus->number, device, where, *data, offset);
 
-	/* check master abort */
+	/* Check master abort */
 	status = au_readl(Au1500_PCI_STATCMD);
 
-	if (status & (1<<29)) {
+	if (status & (1 << 29)) {
 		*data = 0xffffffff;
 		error = -1;
 		DBG("Au1x Master Abort\n");
 	} else if ((status >> 28) & 0xf) {
-		DBG("PCI ERR detected: device %d, status %x\n", device, ((status >> 28) & 0xf));
+		DBG("PCI ERR detected: device %u, status %lx\n",
+		    device, (status >> 28) & 0xf);
 
-		/* clear errors */
+		/* Clear errors */
 		au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD);
 
 		*data = 0xffffffff;
 		error = -1;
 	}
 
-	/* Take away the idsel.
-	*/
-	if (board_pci_idsel) {
+	/* Take away the IDSEL. */
+	if (board_pci_idsel)
 		(void)board_pci_idsel(device, 0);
-	}
 
 	local_irq_restore(flags);
 	return error;
@@ -192,7 +187,7 @@
 }
 
 static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
-			    int where, u8 * val)
+			    int where,	u8 *val)
 {
 	u32 data;
 	int ret;
@@ -206,9 +201,8 @@
 	return ret;
 }
 
-
 static int read_config_word(struct pci_bus *bus, unsigned int devfn,
-			    int where, u16 * val)
+			    int where, u16 *val)
 {
 	u32 data;
 	int ret;
@@ -221,7 +215,7 @@
 }
 
 static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
-			     int where, u32 * val)
+			     int where, u32 *val)
 {
 	int ret;
 
@@ -229,9 +223,8 @@
 	return ret;
 }
 
-static int
-write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
-		  u8 val)
+static int write_config_byte(struct pci_bus *bus, unsigned int devfn,
+			     int where, u8 val)
 {
 	u32 data = 0;
 
@@ -239,7 +232,7 @@
 		return -1;
 
 	data = (data & ~(0xff << ((where & 3) << 3))) |
-	    (val << ((where & 3) << 3));
+	       (val << ((where & 3) << 3));
 
 	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
 		return -1;
@@ -247,9 +240,8 @@
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int
-write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
-		  u16 val)
+static int write_config_word(struct pci_bus *bus, unsigned int devfn,
+			     int where, u16 val)
 {
 	u32 data = 0;
 
@@ -257,18 +249,16 @@
 		return -1;
 
 	data = (data & ~(0xffff << ((where & 3) << 3))) |
-	    (val << ((where & 3) << 3));
+	       (val << ((where & 3) << 3));
 
 	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
 		return -1;
 
-
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int
-write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
-		   u32 val)
+static int write_config_dword(struct pci_bus *bus, unsigned int devfn,
+			      int where, u32 val)
 {
 	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
 		return -1;
@@ -277,18 +267,20 @@
 }
 
 static int config_read(struct pci_bus *bus, unsigned int devfn,
-		       int where, int size, u32 * val)
+		       int where, int size, u32 *val)
 {
 	switch (size) {
 	case 1: {
 			u8 _val;
 			int rc = read_config_byte(bus, devfn, where, &_val);
+
 			*val = _val;
 			return rc;
 		}
-       case 2: {
+	case 2: {
 			u16 _val;
 			int rc = read_config_word(bus, devfn, where, &_val);
+
 			*val = _val;
 			return rc;
 		}
@@ -310,7 +302,6 @@
 	}
 }
 
-
 struct pci_ops au1x_pci_ops = {
 	config_read,
 	config_write
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
index ab96a2d..11769b5 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
@@ -126,9 +126,6 @@
 	struct hwbutton_interrupt *hirq = data;
 	unsigned long cic_ext = *CIC_EXT_CFG_REG;
 
-	if (irq != hirq->irq)
-		return IRQ_NONE;
-
 	if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) {
 		/* Interrupt: pin is now HI */
 		CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
@@ -164,7 +161,7 @@
 	*CIC_EXT_CFG_REG = cic_ext;
 
 	return request_irq(hirq->irq, hwbutton_handler, IRQF_DISABLED,
-				hirq->name, (void *)hirq);
+			   hirq->name, hirq);
 }
 
 static int __init msp_hwbutton_setup(void)
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index 25d3baf..9cebc9e 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -158,7 +158,7 @@
 	}
 }
 
-unsigned int rt_timer_irq;
+int rt_timer_irq;
 
 static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
 {
@@ -219,7 +219,7 @@
 
 static void __init hub_rt_clock_event_global_init(void)
 {
-	unsigned int irq;
+	int irq;
 
 	do {
 		smp_wmb();
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 6a6409a..e856218 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -186,17 +186,6 @@
 	  Say Y here if you are building a kernel for a desktop, embedded
 	  or real-time system.  Say N if you are unsure.
 
-config PREEMPT_BKL
-	bool "Preempt The Big Kernel Lock"
-	depends on PREEMPT
-	default y
-	help
-	  This option reduces the latency of the kernel by making the
-	  big kernel lock preemptible.
-
-	  Say Y here if you are building a kernel for a desktop system.
-	  Say N if you are unsure.
-
 config MN10300_CURRENT_IN_E2
 	bool "Hold current task address in E2 register"
 	default y
diff --git a/arch/mn10300/boot/install.sh b/arch/mn10300/boot/install.sh
index 072951c..abba309 100644
--- a/arch/mn10300/boot/install.sh
+++ b/arch/mn10300/boot/install.sh
@@ -26,42 +26,42 @@
 install -c -m 0755 $2 $4/vmlinuz
 install -c -m 0755 $5 $4/boot.rom
 install -c -m 0755 -d $4/../usr/include/linux
-cd $TOPDIR/include/linux
+cd ${srctree}/include/linux
 for i in `find . -maxdepth 1 -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux
 done
 install -c -m 0755 -d $4/../usr/include/linux/byteorder
-cd $TOPDIR/include/linux/byteorder
+cd ${srctree}/include/linux/byteorder
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/byteorder
 done
 install -c -m 0755 -d $4/../usr/include/linux/lockd
-cd $TOPDIR/include/linux/lockd
+cd ${srctree}/include/linux/lockd
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/lockd
 done
 install -c -m 0755 -d $4/../usr/include/linux/netfilter_ipv4
-cd $TOPDIR/include/linux/netfilter_ipv4
+cd ${srctree}/include/linux/netfilter_ipv4
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/netfilter_ipv4
 done
 install -c -m 0755 -d $4/../usr/include/linux/nfsd
-cd $TOPDIR/include/linux/nfsd
+cd ${srctree}/include/linux/nfsd
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/nfsd/$i
 done
 install -c -m 0755 -d $4/../usr/include/linux/raid
-cd $TOPDIR/include/linux/raid
+cd ${srctree}/include/linux/raid
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/raid
 done
 install -c -m 0755 -d $4/../usr/include/linux/sunrpc
-cd $TOPDIR/include/linux/sunrpc
+cd ${srctree}/include/linux/sunrpc
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/linux/sunrpc
 done
 install -c -m 0755 -d $4/../usr/include/asm
-cd $TOPDIR/include/asm
+cd ${srctree}/include/asm
 for i in `find . -name '*.h' -print`; do
   install -c -m 0644 $i $4/../usr/include/asm
 done
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 1f01284..b0ed709 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -606,7 +606,7 @@
 		int i, j;
 
 		for (i = 0; i < npmem_ranges; i++) {
-			zl = node_zonelist(i);
+			zl = node_zonelist(i, 0);
 			for (j = 0; j < MAX_NR_ZONES; j++) {
 				struct zoneref *z;
 				struct zone *zone;
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index a1ae4d6..72d6756 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -342,9 +342,14 @@
 			/* Outbound ranges, one memory and one IO,
 			 * later cannot be changed. Chip supports a second
 			 * IO range but we don't use it for now
+			 * From the 440EPx user manual:
+			 * PCI 1 Memory     1 8000 0000     1 BFFF FFFF     1GB
+			 * I/O              1 E800 0000     1 E800 FFFF     64KB
+			 * I/O              1 E880 0000     1 EBFF FFFF     56MB
 			 */
-			ranges = <02000000 0 80000000 1 80000000 0 10000000
-				01000000 0 00000000 1 e8000000 0 00100000>;
+			ranges = <02000000 0 80000000 1 80000000 0 40000000
+				01000000 0 00000000 1 e8000000 0 00010000
+				01000000 0 00000000 1 e8800000 0 03800000>;
 
 			/* Inbound 2GB range starting at 0 */
 			dma-ranges = <42000000 0 0 0 0 0 80000000>;
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index d14cebf..2346d27 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -105,6 +105,9 @@
 systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i
 	$(call cmd,systbl_chk)
 
+
+ifeq ($(CONFIG_PPC_MERGE),y)
+
 $(obj)/built-in.o:		prom_init_check
 
 quiet_cmd_prom_init_check = CALL    $<
@@ -114,4 +117,7 @@
 prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o
 	$(call cmd,prom_init_check)
 
+endif
+
+
 clean-files := vmlinux.lds
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index 9f93777..d8f0329 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -16,7 +16,6 @@
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/prom.h>
 #include <asm/processor.h>
 #include <asm/udbg.h>
 
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 36080d4..e44d553 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1208,6 +1208,18 @@
 		.machine_check		= machine_check_4xx,
 		.platform		= "ppc405",
 	},
+	{	/* default match */
+		.pvr_mask		= 0x00000000,
+		.pvr_value		= 0x00000000,
+		.cpu_name		= "(generic 40x PPC)",
+		.cpu_features		= CPU_FTRS_40X,
+		.cpu_user_features	= PPC_FEATURE_32 |
+			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.machine_check		= machine_check_4xx,
+		.platform		= "ppc405",
+	}
 
 #endif /* CONFIG_40x */
 #ifdef CONFIG_44x
@@ -1421,8 +1433,18 @@
 		.machine_check		= machine_check_440A,
 		.platform		= "ppc440",
 	},
+	{	/* default match */
+		.pvr_mask		= 0x00000000,
+		.pvr_value		= 0x00000000,
+		.cpu_name		= "(generic 44x PPC)",
+		.cpu_features		= CPU_FTRS_44X,
+		.cpu_user_features	= COMMON_USER_BOOKE,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.machine_check		= machine_check_4xx,
+		.platform		= "ppc440",
+	}
 #endif /* CONFIG_44x */
-#ifdef CONFIG_FSL_BOOKE
 #ifdef CONFIG_E200
 	{	/* e200z5 */
 		.pvr_mask		= 0xfff00000,
@@ -1451,7 +1473,20 @@
 		.machine_check		= machine_check_e200,
 		.platform		= "ppc5554",
 	},
-#elif defined(CONFIG_E500)
+	{	/* default match */
+		.pvr_mask		= 0x00000000,
+		.pvr_value		= 0x00000000,
+		.cpu_name		= "(generic E200 PPC)",
+		.cpu_features		= CPU_FTRS_E200,
+		.cpu_user_features	= COMMON_USER_BOOKE |
+			PPC_FEATURE_HAS_EFP_SINGLE |
+			PPC_FEATURE_UNIFIED_CACHE,
+		.dcache_bsize		= 32,
+		.machine_check		= machine_check_e200,
+		.platform		= "ppc5554",
+	}
+#endif /* CONFIG_E200 */
+#ifdef CONFIG_E500
 	{	/* e500 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x80200000,
@@ -1487,20 +1522,20 @@
 		.machine_check		= machine_check_e500,
 		.platform		= "ppc8548",
 	},
-#endif
-#endif
-#if !CLASSIC_PPC
 	{	/* default match */
 		.pvr_mask		= 0x00000000,
 		.pvr_value		= 0x00000000,
-		.cpu_name		= "(generic PPC)",
-		.cpu_features		= CPU_FTRS_GENERIC_32,
-		.cpu_user_features	= PPC_FEATURE_32,
+		.cpu_name		= "(generic E500 PPC)",
+		.cpu_features		= CPU_FTRS_E500,
+		.cpu_user_features	= COMMON_USER_BOOKE |
+			PPC_FEATURE_HAS_SPE_COMP |
+			PPC_FEATURE_HAS_EFP_SINGLE_COMP,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.machine_check		= machine_check_e500,
 		.platform		= "powerpc",
 	}
-#endif /* !CLASSIC_PPC */
+#endif /* CONFIG_E500 */
 #endif /* CONFIG_PPC32 */
 };
 
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index b84ec6a..c2b9dc4 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -653,7 +653,14 @@
 	rlwimi	r10, r11, 0, 26, 26		/* UX = HWEXEC & USER */
 
 	rlwimi	r12, r10, 0, 26, 31		/* Insert static perms */
-	rlwinm	r12, r12, 0, 20, 15		/* Clear U0-U3 */
+
+	/*
+	 * Clear U0-U3 and WL1 IL1I IL1D IL2I IL2D bits which are added
+	 * on newer 440 cores like the 440x6 used on AMCC 460EX/460GT (see
+	 * include/asm-powerpc/pgtable-ppc32.h for details).
+	 */
+	rlwinm	r12, r12, 0, 20, 10
+
 	tlbwe	r12, r13, PPC44x_TLB_ATTRIB	/* Write ATTRIB */
 
 	/* Done...restore registers and get out of here.
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 024805e..25e84c0 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1517,10 +1517,6 @@
 	addi	r2,r2,0x4000
 	add	r2,r2,r26
 
-	/* Set initial ptr to current */
-	LOAD_REG_IMMEDIATE(r4, init_task)
-	std	r4,PACACURRENT(r13)
-
 	/* Do very early kernel initializations, including initial hash table,
 	 * stab and slb setup before we turn on relocation.	*/
 
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c
index 289af34..4d5731b 100644
--- a/arch/powerpc/kernel/isa-bridge.c
+++ b/arch/powerpc/kernel/isa-bridge.c
@@ -108,9 +108,6 @@
 	if (size > 0x10000)
 		size = 0x10000;
 
-	printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
-	       "mapping 64k\n");
-
 	__ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
 		     size, _PAGE_NO_CACHE|_PAGE_GUARDED);
 	return;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 25e3fd8..098fd96 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -170,6 +170,8 @@
 
 void __init early_setup(unsigned long dt_ptr)
 {
+	/* -------- printk is _NOT_ safe to use here ! ------- */
+
 	/* Fill in any unititialised pacas */
 	initialise_pacas();
 
@@ -179,12 +181,14 @@
 	/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
 	setup_paca(0);
 
-	/* Enable early debugging if any specified (see udbg.h) */
-	udbg_early_init();
-
 	/* Initialize lockdep early or else spinlocks will blow */
 	lockdep_init();
 
+	/* -------- printk is now safe to use ------- */
+
+	/* Enable early debugging if any specified (see udbg.h) */
+	udbg_early_init();
+
  	DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr);
 
 	/*
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 4bb023f..c71d37d 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -10,6 +10,7 @@
 obj-y			:= string.o alloc.o \
 			   checksum_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC32)	+= div64.o copy_32.o
+obj-$(CONFIG_HAS_IOMEM)	+= devres.o
 endif
 
 obj-$(CONFIG_PPC64)	+= copypage_64.o copyuser_64.o \
diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c
new file mode 100644
index 0000000..292115d
--- /dev/null
+++ b/arch/powerpc/lib/devres.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 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/device.h>	/* devres_*(), devm_ioremap_release() */
+#include <linux/io.h>		/* ioremap_flags() */
+#include <linux/module.h>	/* EXPORT_SYMBOL() */
+
+/**
+ * devm_ioremap_prot - Managed ioremap_flags()
+ * @dev: Generic device to remap IO address for
+ * @offset: BUS offset to map
+ * @size: Size of map
+ * @flags: Page flags
+ *
+ * Managed ioremap_prot().  Map is automatically unmapped on driver
+ * detach.
+ */
+void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
+				 size_t size, unsigned long flags)
+{
+	void __iomem **ptr, *addr;
+
+	ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return NULL;
+
+	addr = ioremap_flags(offset, size, flags);
+	if (addr) {
+		*ptr = addr;
+		devres_add(dev, ptr);
+	} else
+		devres_free(ptr);
+
+	return addr;
+}
+EXPORT_SYMBOL(devm_ioremap_prot);
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 04f74f9..5bf7df1 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -35,6 +35,7 @@
 #include <linux/percpu.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
+#include <linux/kernel_stat.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -231,6 +232,54 @@
 				    "IBM,CBEA-Internal-Interrupt-Controller");
 }
 
+extern int noirqdebug;
+
+static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
+{
+	const unsigned int cpu = smp_processor_id();
+
+	spin_lock(&desc->lock);
+
+	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+	/*
+	 * If we're currently running this IRQ, or its disabled,
+	 * we shouldn't process the IRQ. Mark it pending, handle
+	 * the necessary masking and go out
+	 */
+	if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
+		    !desc->action)) {
+		desc->status |= IRQ_PENDING;
+		goto out_eoi;
+	}
+
+	kstat_cpu(cpu).irqs[irq]++;
+
+	/* Mark the IRQ currently in progress.*/
+	desc->status |= IRQ_INPROGRESS;
+
+	do {
+		struct irqaction *action = desc->action;
+		irqreturn_t action_ret;
+
+		if (unlikely(!action))
+			goto out_eoi;
+
+		desc->status &= ~IRQ_PENDING;
+		spin_unlock(&desc->lock);
+		action_ret = handle_IRQ_event(irq, action);
+		if (!noirqdebug)
+			note_interrupt(irq, desc, action_ret);
+		spin_lock(&desc->lock);
+
+	} while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
+
+	desc->status &= ~IRQ_INPROGRESS;
+out_eoi:
+	desc->chip->eoi(irq);
+	spin_unlock(&desc->lock);
+}
+
 static int iic_host_map(struct irq_host *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
@@ -240,10 +289,10 @@
 		break;
 	case IIC_IRQ_TYPE_IOEXC:
 		set_irq_chip_and_handler(virq, &iic_ioexc_chip,
-					 handle_fasteoi_irq);
+					 handle_iic_irq);
 		break;
 	default:
-		set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
+		set_irq_chip_and_handler(virq, &iic_chip, handle_iic_irq);
 	}
 	return 0;
 }
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 6bab44b..70c6601 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -141,6 +141,10 @@
 
 	if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
 		out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
+	else {
+		set_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags);
+		mb();
+	}
 }
 
 static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
@@ -226,11 +230,13 @@
 		return 0;
 	}
 
-	spu->class_0_pending = 0;
-	spu->dar = ea;
-	spu->dsisr = dsisr;
+	spu->class_1_dar = ea;
+	spu->class_1_dsisr = dsisr;
 
-	spu->stop_callback(spu);
+	spu->stop_callback(spu, 1);
+
+	spu->class_1_dar = 0;
+	spu->class_1_dsisr = 0;
 
 	return 0;
 }
@@ -318,11 +324,15 @@
 	stat = spu_int_stat_get(spu, 0) & mask;
 
 	spu->class_0_pending |= stat;
-	spu->dsisr = spu_mfc_dsisr_get(spu);
-	spu->dar = spu_mfc_dar_get(spu);
+	spu->class_0_dsisr = spu_mfc_dsisr_get(spu);
+	spu->class_0_dar = spu_mfc_dar_get(spu);
 	spin_unlock(&spu->register_lock);
 
-	spu->stop_callback(spu);
+	spu->stop_callback(spu, 0);
+
+	spu->class_0_pending = 0;
+	spu->class_0_dsisr = 0;
+	spu->class_0_dar = 0;
 
 	spu_int_stat_clear(spu, 0, stat);
 
@@ -363,6 +373,9 @@
 	if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR)
 		;
 
+	spu->class_1_dsisr = 0;
+	spu->class_1_dar = 0;
+
 	return stat ? IRQ_HANDLED : IRQ_NONE;
 }
 
@@ -396,10 +409,10 @@
 		spu->ibox_callback(spu);
 
 	if (stat & CLASS2_SPU_STOP_INTR)
-		spu->stop_callback(spu);
+		spu->stop_callback(spu, 2);
 
 	if (stat & CLASS2_SPU_HALT_INTR)
-		spu->stop_callback(spu);
+		spu->stop_callback(spu, 2);
 
 	if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR)
 		spu->mfc_callback(spu);
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
index 67fa724..906a0a2 100644
--- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c
+++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
+#include <linux/sched.h>
 
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
@@ -75,8 +76,19 @@
 
 static void cpu_affinity_set(struct spu *spu, int cpu)
 {
-	u64 target = iic_get_target_id(cpu);
-	u64 route = target << 48 | target << 32 | target << 16;
+	u64 target;
+	u64 route;
+
+	if (nr_cpus_node(spu->node)) {
+		cpumask_t spumask = node_to_cpumask(spu->node);
+		cpumask_t cpumask = node_to_cpumask(cpu_to_node(cpu));
+
+		if (!cpus_intersects(spumask, cpumask))
+			return;
+	}
+
+	target = iic_get_target_id(cpu);
+	route = target << 48 | target << 32 | target << 16;
 	out_be64(&spu->priv1->int_route_RW, route);
 }
 
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index e46d300..f093a58 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -83,13 +83,18 @@
 		return 0;
 
 	if (stat & CLASS0_DMA_ALIGNMENT_INTR)
-		spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_DMA_ALIGNMENT);
+		spufs_handle_event(ctx, ctx->csa.class_0_dar,
+			SPE_EVENT_DMA_ALIGNMENT);
 
 	if (stat & CLASS0_INVALID_DMA_COMMAND_INTR)
-		spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_INVALID_DMA);
+		spufs_handle_event(ctx, ctx->csa.class_0_dar,
+			SPE_EVENT_INVALID_DMA);
 
 	if (stat & CLASS0_SPU_ERROR_INTR)
-		spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_SPE_ERROR);
+		spufs_handle_event(ctx, ctx->csa.class_0_dar,
+			SPE_EVENT_SPE_ERROR);
+
+	ctx->csa.class_0_pending = 0;
 
 	return -EIO;
 }
@@ -119,8 +124,8 @@
 	 * in time, we can still expect to get the same fault
 	 * the immediately after the context restore.
 	 */
-	ea = ctx->csa.dar;
-	dsisr = ctx->csa.dsisr;
+	ea = ctx->csa.class_1_dar;
+	dsisr = ctx->csa.class_1_dsisr;
 
 	if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)))
 		return 0;
@@ -158,7 +163,7 @@
 	 * time slicing will not preempt the context while the page fault
 	 * handler is running. Context switch code removes mappings.
 	 */
-	ctx->csa.dar = ctx->csa.dsisr = 0;
+	ctx->csa.class_1_dar = ctx->csa.class_1_dsisr = 0;
 
 	/*
 	 * If we handled the fault successfully and are in runnable
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 0c32a05..f407b24 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -23,6 +23,7 @@
 
 #include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/fsnotify.h>
 #include <linux/backing-dev.h>
 #include <linux/init.h>
 #include <linux/ioctl.h>
@@ -223,7 +224,7 @@
 	parent = dir->d_parent->d_inode;
 	ctx = SPUFS_I(dir->d_inode)->i_ctx;
 
-	mutex_lock(&parent->i_mutex);
+	mutex_lock_nested(&parent->i_mutex, I_MUTEX_PARENT);
 	ret = spufs_rmdir(parent, dir);
 	mutex_unlock(&parent->i_mutex);
 	WARN_ON(ret);
@@ -618,12 +619,15 @@
 	mode &= ~current->fs->umask;
 
 	if (flags & SPU_CREATE_GANG)
-		return spufs_create_gang(nd->path.dentry->d_inode,
+		ret = spufs_create_gang(nd->path.dentry->d_inode,
 					 dentry, nd->path.mnt, mode);
 	else
-		return spufs_create_context(nd->path.dentry->d_inode,
+		ret = spufs_create_context(nd->path.dentry->d_inode,
 					    dentry, nd->path.mnt, flags, mode,
 					    filp);
+	if (ret >= 0)
+		fsnotify_mkdir(nd->path.dentry->d_inode, dentry);
+	return ret;
 
 out_dput:
 	dput(dentry);
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index a9c35b7..b7493b8 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -11,7 +11,7 @@
 #include "spufs.h"
 
 /* interrupt-level stop callback function. */
-void spufs_stop_callback(struct spu *spu)
+void spufs_stop_callback(struct spu *spu, int irq)
 {
 	struct spu_context *ctx = spu->ctx;
 
@@ -24,9 +24,19 @@
 	 */
 	if (ctx) {
 		/* Copy exception arguments into module specific structure */
-		ctx->csa.class_0_pending = spu->class_0_pending;
-		ctx->csa.dsisr = spu->dsisr;
-		ctx->csa.dar = spu->dar;
+		switch(irq) {
+		case 0 :
+			ctx->csa.class_0_pending = spu->class_0_pending;
+			ctx->csa.class_0_dsisr = spu->class_0_dsisr;
+			ctx->csa.class_0_dar = spu->class_0_dar;
+			break;
+		case 1 :
+			ctx->csa.class_1_dsisr = spu->class_1_dsisr;
+			ctx->csa.class_1_dar = spu->class_1_dar;
+			break;
+		case 2 :
+			break;
+		}
 
 		/* ensure that the exception status has hit memory before a
 		 * thread waiting on the context's stop queue is woken */
@@ -34,11 +44,6 @@
 
 		wake_up_all(&ctx->stop_wq);
 	}
-
-	/* Clear callback arguments from spu structure */
-	spu->class_0_pending = 0;
-	spu->dsisr = 0;
-	spu->dar = 0;
 }
 
 int spu_stopped(struct spu_context *ctx, u32 *stat)
@@ -56,7 +61,11 @@
 	if (!(*stat & SPU_STATUS_RUNNING) && (*stat & stopped))
 		return 1;
 
-	dsisr = ctx->csa.dsisr;
+	dsisr = ctx->csa.class_0_dsisr;
+	if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
+		return 1;
+
+	dsisr = ctx->csa.class_1_dsisr;
 	if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
 		return 1;
 
@@ -294,7 +303,7 @@
 	u32 ls_pointer, npc;
 	void __iomem *ls;
 	long spu_ret;
-	int ret, ret2;
+	int ret;
 
 	/* get syscall block from local store */
 	npc = ctx->ops->npc_read(ctx) & ~3;
@@ -316,11 +325,9 @@
 		if (spu_ret <= -ERESTARTSYS) {
 			ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
 		}
-		ret2 = spu_acquire(ctx);
+		mutex_lock(&ctx->state_mutex);
 		if (ret == -ERESTARTSYS)
 			return ret;
-		if (ret2)
-			return -EINTR;
 	}
 
 	/* need to re-get the ls, as it may have changed when we released the
@@ -343,13 +350,14 @@
 	if (mutex_lock_interruptible(&ctx->run_mutex))
 		return -ERESTARTSYS;
 
-	spu_enable_spu(ctx);
 	ctx->event_return = 0;
 
 	ret = spu_acquire(ctx);
 	if (ret)
 		goto out_unlock;
 
+	spu_enable_spu(ctx);
+
 	spu_update_sched_info(ctx);
 
 	ret = spu_run_init(ctx, npc);
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 7298e7d..2e411f2 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -140,6 +140,9 @@
 	 * if it is timesliced or preempted.
 	 */
 	ctx->cpus_allowed = current->cpus_allowed;
+
+	/* Save the current cpu id for spu interrupt routing. */
+	ctx->last_ran = raw_smp_processor_id();
 }
 
 void spu_update_sched_info(struct spu_context *ctx)
@@ -243,7 +246,6 @@
 	spu_switch_log_notify(spu, ctx, SWITCH_LOG_START, 0);
 	spu_restore(&ctx->csa, spu);
 	spu->timestamp = jiffies;
-	spu_cpu_affinity_set(spu, raw_smp_processor_id());
 	spu_switch_notify(spu, ctx);
 	ctx->state = SPU_STATE_RUNNABLE;
 
@@ -657,7 +659,8 @@
 
 			victim->stats.invol_ctx_switch++;
 			spu->stats.invol_ctx_switch++;
-			spu_add_to_rq(victim);
+			if (test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags))
+				spu_add_to_rq(victim);
 
 			mutex_unlock(&victim->state_mutex);
 
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 7312745..454c277 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -121,6 +121,7 @@
 	cpumask_t cpus_allowed;
 	int policy;
 	int prio;
+	int last_ran;
 
 	/* statistics */
 	struct {
@@ -331,7 +332,7 @@
 /* irq callback funcs. */
 void spufs_ibox_callback(struct spu *spu);
 void spufs_wbox_callback(struct spu *spu);
-void spufs_stop_callback(struct spu *spu);
+void spufs_stop_callback(struct spu *spu, int irq);
 void spufs_mfc_callback(struct spu *spu);
 void spufs_dma_callback(struct spu *spu, int type);
 
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index d2a1249..3df9a36 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -132,6 +132,14 @@
 	spu_int_mask_set(spu, 2, 0ul);
 	eieio();
 	spin_unlock_irq(&spu->register_lock);
+
+	/*
+	 * This flag needs to be set before calling synchronize_irq so
+	 * that the update will be visible to the relevant handlers
+	 * via a simple load.
+	 */
+	set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
+	clear_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags);
 	synchronize_irq(spu->irqs[0]);
 	synchronize_irq(spu->irqs[1]);
 	synchronize_irq(spu->irqs[2]);
@@ -166,9 +174,8 @@
 	/* Save, Step 7:
 	 * Restore, Step 5:
 	 *     Set a software context switch pending flag.
+	 *     Done above in Step 3 - disable_interrupts().
 	 */
-	set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
-	mb();
 }
 
 static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu)
@@ -186,20 +193,21 @@
 				 MFC_CNTL_SUSPEND_COMPLETE);
 		/* fall through */
 	case MFC_CNTL_SUSPEND_COMPLETE:
-		if (csa) {
+		if (csa)
 			csa->priv2.mfc_control_RW =
-				MFC_CNTL_SUSPEND_MASK |
+				in_be64(&priv2->mfc_control_RW) |
 				MFC_CNTL_SUSPEND_DMA_QUEUE;
-		}
 		break;
 	case MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION:
 		out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE);
 		POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) &
 				  MFC_CNTL_SUSPEND_DMA_STATUS_MASK) ==
 				 MFC_CNTL_SUSPEND_COMPLETE);
-		if (csa) {
-			csa->priv2.mfc_control_RW = 0;
-		}
+		if (csa)
+			csa->priv2.mfc_control_RW =
+				in_be64(&priv2->mfc_control_RW) &
+				~MFC_CNTL_SUSPEND_DMA_QUEUE &
+				~MFC_CNTL_SUSPEND_MASK;
 		break;
 	}
 }
@@ -249,16 +257,21 @@
 	}
 }
 
-static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu)
+static inline void save_mfc_stopped_status(struct spu_state *csa,
+		struct spu *spu)
 {
 	struct spu_priv2 __iomem *priv2 = spu->priv2;
+	const u64 mask = MFC_CNTL_DECREMENTER_RUNNING |
+			MFC_CNTL_DMA_QUEUES_EMPTY;
 
 	/* Save, Step 12:
 	 *     Read MFC_CNTL[Ds].  Update saved copy of
 	 *     CSA.MFC_CNTL[Ds].
+	 *
+	 * update: do the same with MFC_CNTL[Q].
 	 */
-	csa->priv2.mfc_control_RW |=
-		in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING;
+	csa->priv2.mfc_control_RW &= ~mask;
+	csa->priv2.mfc_control_RW |= in_be64(&priv2->mfc_control_RW) & mask;
 }
 
 static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu)
@@ -462,7 +475,9 @@
 	 * Restore, Step 14.
 	 *     Write MFC_CNTL[Pc]=1 (purge queue).
 	 */
-	out_be64(&priv2->mfc_control_RW, MFC_CNTL_PURGE_DMA_REQUEST);
+	out_be64(&priv2->mfc_control_RW,
+			MFC_CNTL_PURGE_DMA_REQUEST |
+			MFC_CNTL_SUSPEND_MASK);
 	eieio();
 }
 
@@ -725,10 +740,14 @@
 	/* Save, Step 48:
 	 * Restore, Step 23.
 	 *     Change the software context switch pending flag
-	 *     to context switch active.
+	 *     to context switch active.  This implementation does
+	 *     not uses a switch active flag.
 	 *
-	 *     This implementation does not uses a switch active flag.
+	 * Now that we have saved the mfc in the csa, we can add in the
+	 * restart command if an exception occurred.
 	 */
+	if (test_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags))
+		csa->priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND;
 	clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
 	mb();
 }
@@ -1690,6 +1709,13 @@
 	eieio();
 }
 
+static inline void set_int_route(struct spu_state *csa, struct spu *spu)
+{
+	struct spu_context *ctx = spu->ctx;
+
+	spu_cpu_affinity_set(spu, ctx->last_ran);
+}
+
 static inline void restore_other_spu_access(struct spu_state *csa,
 					    struct spu *spu)
 {
@@ -1721,15 +1747,15 @@
 	 */
 	out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW);
 	eieio();
+
 	/*
-	 * FIXME: this is to restart a DMA that we were processing
-	 *        before the save. better remember the fault information
-	 *        in the csa instead.
+	 * The queue is put back into the same state that was evident prior to
+	 * the context switch. The suspend flag is added to the saved state in
+	 * the csa, if the operational state was suspending or suspended. In
+	 * this case, the code that suspended the mfc is responsible for
+	 * continuing it. Note that SPE faults do not change the operational
+	 * state of the spu.
 	 */
-	if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) {
-		out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
-		eieio();
-	}
 }
 
 static inline void enable_user_access(struct spu_state *csa, struct spu *spu)
@@ -1788,7 +1814,7 @@
 	save_spu_runcntl(prev, spu);	        /* Step 9. */
 	save_mfc_sr1(prev, spu);	        /* Step 10. */
 	save_spu_status(prev, spu);	        /* Step 11. */
-	save_mfc_decr(prev, spu);	        /* Step 12. */
+	save_mfc_stopped_status(prev, spu);     /* Step 12. */
 	halt_mfc_decr(prev, spu);	        /* Step 13. */
 	save_timebase(prev, spu);		/* Step 14. */
 	remove_other_spu_access(prev, spu);	/* Step 15. */
@@ -2000,6 +2026,7 @@
 	check_ppuint_mb_stat(next, spu);	/* Step 67. */
 	spu_invalidate_slbs(spu);		/* Modified Step 68. */
 	restore_mfc_sr1(next, spu);	        /* Step 69. */
+	set_int_route(next, spu);		/* NEW      */
 	restore_other_spu_access(next, spu);	/* Step 70. */
 	restore_spu_runcntl(next, spu);	        /* Step 71. */
 	restore_mfc_cntl(next, spu);	        /* Step 72. */
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 5bcc58d..130ff72 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -58,7 +58,9 @@
 
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+	.shared		= &mv643xx_eth_shared_device,
 	.port_number	= 0,
+
 	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
 	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
 	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
@@ -88,7 +90,9 @@
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+	.shared		= &mv643xx_eth_shared_device,
 	.port_number	= 1,
+
 	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
 	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
 	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index bec3803..417eca7 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -55,11 +55,6 @@
         dp = PDE(inode);
  	data = (unsigned int *)dp->data;
 
-	if (!data) {
-		printk(KERN_ERR "scanlog: read failed no data\n");
-		return -EIO;
-	}
-
 	if (count > RTAS_DATA_BUF_SIZE)
 		count = RTAS_DATA_BUF_SIZE;
 
@@ -146,11 +141,6 @@
 	struct proc_dir_entry *dp = PDE(inode);
 	unsigned int *data = (unsigned int *)dp->data;
 
-	if (!data) {
-		printk(KERN_ERR "scanlog: open failed no data\n");
-		return -EIO;
-	}
-
 	if (data[0] != 0) {
 		/* This imperfect test stops a second copy of the
 		 * data (or a reset while data is being copied)
@@ -168,10 +158,6 @@
 	struct proc_dir_entry *dp = PDE(inode);
 	unsigned int *data = (unsigned int *)dp->data;
 
-	if (!data) {
-		printk(KERN_ERR "scanlog: release failed no data\n");
-		return -EIO;
-	}
 	data[0] = 0;
 
 	return 0;
@@ -200,12 +186,11 @@
 	if (!data)
 		goto err;
 
-	ent = proc_create("ppc64/rtas/scan-log-dump", S_IRUSR, NULL,
-			  &scanlog_fops);
+	ent = proc_create_data("ppc64/rtas/scan-log-dump", S_IRUSR, NULL,
+			       &scanlog_fops, data);
 	if (!ent)
 		goto err;
 
-	ent->data = data;
 	proc_ppc64_scan_log_dump = ent;
 
 	return 0;
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 41af122..a132e0d 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -239,6 +239,8 @@
 
 	memset(&pdata, 0, sizeof(pdata));
 
+	pdata.shared = shared_pdev;
+
 	prop = of_get_property(np, "reg", NULL);
 	if (!prop)
 		return -ENODEV;
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 1814adb..b4a54c5 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1387,28 +1387,59 @@
 	resource_size_t size = res->end - res->start + 1;
 	u64 sa;
 
-	/* Calculate window size */
-	sa = (0xffffffffffffffffull << ilog2(size));;
-	if (res->flags & IORESOURCE_PREFETCH)
-		sa |= 0x8;
+	if (port->endpoint) {
+		resource_size_t ep_addr = 0;
+		resource_size_t ep_size = 32 << 20;
 
-	out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
-	out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
+		/* Currently we map a fixed 64MByte window to PLB address
+		 * 0 (SDRAM). This should probably be configurable via a dts
+		 * property.
+		 */
 
-	/* The setup of the split looks weird to me ... let's see if it works */
-	out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
-	out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
-	out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
-	out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
-	out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
-	out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
+		/* Calculate window size */
+		sa = (0xffffffffffffffffull << ilog2(ep_size));;
+
+		/* Setup BAR0 */
+		out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
+		out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa) |
+			 PCI_BASE_ADDRESS_MEM_TYPE_64);
+
+		/* Disable BAR1 & BAR2 */
+		out_le32(mbase + PECFG_BAR1MPA, 0);
+		out_le32(mbase + PECFG_BAR2HMPA, 0);
+		out_le32(mbase + PECFG_BAR2LMPA, 0);
+
+		out_le32(mbase + PECFG_PIM01SAH, RES_TO_U32_HIGH(sa));
+		out_le32(mbase + PECFG_PIM01SAL, RES_TO_U32_LOW(sa));
+
+		out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(ep_addr));
+		out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(ep_addr));
+	} else {
+		/* Calculate window size */
+		sa = (0xffffffffffffffffull << ilog2(size));;
+		if (res->flags & IORESOURCE_PREFETCH)
+			sa |= 0x8;
+
+		out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
+		out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
+
+		/* The setup of the split looks weird to me ... let's see
+		 * if it works
+		 */
+		out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
+		out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
+		out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
+		out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
+		out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
+		out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
+
+		out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start));
+		out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start));
+	}
 
 	/* Enable inbound mapping */
 	out_le32(mbase + PECFG_PIMEN, 0x1);
 
-	out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start));
-	out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start));
-
 	/* Enable I/O, Mem, and Busmaster cycles */
 	out_le16(mbase + PCI_COMMAND,
 		 in_le16(mbase + PCI_COMMAND) |
@@ -1422,13 +1453,8 @@
 	const int *bus_range;
 	int primary = 0, busses;
 	void __iomem *mbase = NULL, *cfg_data = NULL;
-
-	/* XXX FIXME: Handle endpoint mode properly */
-	if (port->endpoint) {
-		printk(KERN_WARNING "PCIE%d: Port in endpoint mode !\n",
-		       port->index);
-		return;
-	}
+	const u32 *pval;
+	u32 val;
 
 	/* Check if primary bridge */
 	if (of_get_property(port->node, "primary", NULL))
@@ -1462,21 +1488,30 @@
 		hose->last_busno = hose->first_busno + busses;
 	}
 
-	/* We map the external config space in cfg_data and the host config
-	 * space in cfg_addr. External space is 1M per bus, internal space
-	 * is 4K
+	if (!port->endpoint) {
+		/* Only map the external config space in cfg_data for
+		 * PCIe root-complexes. External space is 1M per bus
+		 */
+		cfg_data = ioremap(port->cfg_space.start +
+				   (hose->first_busno + 1) * 0x100000,
+				   busses * 0x100000);
+		if (cfg_data == NULL) {
+			printk(KERN_ERR "%s: Can't map external config space !",
+			       port->node->full_name);
+			goto fail;
+		}
+		hose->cfg_data = cfg_data;
+	}
+
+	/* Always map the host config space in cfg_addr.
+	 * Internal space is 4K
 	 */
-	cfg_data = ioremap(port->cfg_space.start +
-				 (hose->first_busno + 1) * 0x100000,
-				 busses * 0x100000);
 	mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
-	if (cfg_data == NULL || mbase == NULL) {
-		printk(KERN_ERR "%s: Can't map config space !",
+	if (mbase == NULL) {
+		printk(KERN_ERR "%s: Can't map internal config space !",
 		       port->node->full_name);
 		goto fail;
 	}
-
-	hose->cfg_data = cfg_data;
 	hose->cfg_addr = mbase;
 
 	pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name,
@@ -1489,12 +1524,14 @@
 	port->hose = hose;
 	mbase = (void __iomem *)hose->cfg_addr;
 
-	/*
-	 * Set bus numbers on our root port
-	 */
-	out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno);
-	out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1);
-	out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno);
+	if (!port->endpoint) {
+		/*
+		 * Set bus numbers on our root port
+		 */
+		out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno);
+		out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1);
+		out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno);
+	}
 
 	/*
 	 * OMRs are already reset, also disable PIMs
@@ -1515,17 +1552,49 @@
 	ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window);
 
 	/* The root complex doesn't show up if we don't set some vendor
-	 * and device IDs into it. Those are the same bogus one that the
-	 * initial code in arch/ppc add. We might want to change that.
+	 * and device IDs into it. The defaults below are the same bogus
+	 * one that the initial code in arch/ppc had. This can be
+	 * overwritten by setting the "vendor-id/device-id" properties
+	 * in the pciex node.
 	 */
-	out_le16(mbase + 0x200, 0xaaa0 + port->index);
-	out_le16(mbase + 0x202, 0xbed0 + port->index);
 
-	/* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
-	out_le32(mbase + 0x208, 0x06040001);
+	/* Get the (optional) vendor-/device-id from the device-tree */
+	pval = of_get_property(port->node, "vendor-id", NULL);
+	if (pval) {
+		val = *pval;
+	} else {
+		if (!port->endpoint)
+			val = 0xaaa0 + port->index;
+		else
+			val = 0xeee0 + port->index;
+	}
+	out_le16(mbase + 0x200, val);
 
-	printk(KERN_INFO "PCIE%d: successfully set as root-complex\n",
-	       port->index);
+	pval = of_get_property(port->node, "device-id", NULL);
+	if (pval) {
+		val = *pval;
+	} else {
+		if (!port->endpoint)
+			val = 0xbed0 + port->index;
+		else
+			val = 0xfed0 + port->index;
+	}
+	out_le16(mbase + 0x202, val);
+
+	if (!port->endpoint) {
+		/* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
+		out_le32(mbase + 0x208, 0x06040001);
+
+		printk(KERN_INFO "PCIE%d: successfully set as root-complex\n",
+		       port->index);
+	} else {
+		/* Set Class Code to Processor/PPC */
+		out_le32(mbase + 0x208, 0x0b200001);
+
+		printk(KERN_INFO "PCIE%d: successfully set as endpoint\n",
+		       port->index);
+	}
+
 	return;
  fail:
 	if (hose)
@@ -1542,6 +1611,7 @@
 	const u32 *pval;
 	int portno;
 	unsigned int dcrs;
+	const char *val;
 
 	/* First, proceed to core initialization as we assume there's
 	 * only one PCIe core in the system
@@ -1573,8 +1643,20 @@
 	}
 	port->sdr_base = *pval;
 
-	/* XXX Currently, we only support root complex mode */
-	port->endpoint = 0;
+	/* Check if device_type property is set to "pci" or "pci-endpoint".
+	 * Resulting from this setup this PCIe port will be configured
+	 * as root-complex or as endpoint.
+	 */
+	val = of_get_property(port->node, "device_type", NULL);
+	if (!strcmp(val, "pci-endpoint")) {
+		port->endpoint = 1;
+	} else if (!strcmp(val, "pci")) {
+		port->endpoint = 0;
+	} else {
+		printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n",
+		       np->full_name);
+		return;
+	}
 
 	/* Fetch config space registers address */
 	if (of_address_to_resource(np, 0, &port->cfg_space)) {
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 52c7478..1702de9 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2842,9 +2842,11 @@
 	DUMP_FIELD(spu, "0x%lx", ls_size);
 	DUMP_FIELD(spu, "0x%x", node);
 	DUMP_FIELD(spu, "0x%lx", flags);
-	DUMP_FIELD(spu, "0x%lx", dar);
-	DUMP_FIELD(spu, "0x%lx", dsisr);
 	DUMP_FIELD(spu, "%d", class_0_pending);
+	DUMP_FIELD(spu, "0x%lx", class_0_dar);
+	DUMP_FIELD(spu, "0x%lx", class_0_dsisr);
+	DUMP_FIELD(spu, "0x%lx", class_1_dar);
+	DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
 	DUMP_FIELD(spu, "0x%lx", irqs[0]);
 	DUMP_FIELD(spu, "0x%lx", irqs[1]);
 	DUMP_FIELD(spu, "0x%lx", irqs[2]);
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 8df7f0e..2352d13 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -43,7 +43,7 @@
 KBUILD_CFLAGS += $(cpu-as-y)
 
 # Default to the common case.
-KBUILD_DEFCONFIG := common_defconfig
+KBUILD_DEFCONFIG := ebony_defconfig
 
 head-y				:= arch/ppc/kernel/head.o
 head-$(CONFIG_8xx)		:= arch/ppc/kernel/head_8xx.o
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 16ac11c..602c268 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -24,6 +24,7 @@
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
 #include <linux/adb.h>
 #include <linux/cuda.h>
 #include <linux/pmu.h>
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index bfddfde..51e8094 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -36,6 +36,7 @@
 #include <asm/nvram.h>
 #include <asm/xmon.h>
 #include <asm/ocp.h>
+#include <asm/irq.h>
 
 #define USES_PPC_SYS (defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
 		      defined(CONFIG_PPC_MPC52xx))
diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c
index 18495e7..d687b0f 100644
--- a/arch/ppc/platforms/residual.c
+++ b/arch/ppc/platforms/residual.c
@@ -38,6 +38,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sections.h>
 #include <asm/mmu.h>
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 90fe904..418f305 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -341,6 +341,7 @@
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+	.shared		= &mv64x60_eth_shared_device;
 	.port_number	= 0,
 };
 
@@ -366,6 +367,7 @@
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+	.shared		= &mv64x60_eth_shared_device;
 	.port_number	= 1,
 };
 
@@ -391,6 +393,7 @@
 };
 
 static struct mv643xx_eth_platform_data eth2_pd = {
+	.shared		= &mv64x60_eth_shared_device;
 	.port_number	= 2,
 };
 
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 29a7940..1d03508 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -430,6 +430,13 @@
 	  Select this option to enable the special message interface to
 	  the cooperative memory management.
 
+config PAGE_STATES
+	bool "Unused page notification"
+	help
+	  This enables the notification of unused pages to the
+	  hypervisor. The ESSA instruction is used to do the states
+	  changes between a page that has content and the unused state.
+
 config VIRT_TIMER
 	bool "Virtual CPU timer support"
 	help
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 743d54f..d003a6e 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -121,7 +121,7 @@
 	lgfr	%r3,%r3			# long
 	llgtr	%r4,%r4			# long
 	llgfr	%r5,%r5			# long
-	jg	sys_ptrace		# branch to system call
+	jg	compat_sys_ptrace	# branch to system call
 
 	.globl	sys32_alarm_wrapper
 sys32_alarm_wrapper:
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index bdbb3bc..708cf9c 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -279,8 +279,6 @@
 	st	%r2,SP_R2(%r15)   # store return value (change R2 on stack)
 
 sysc_return:
-	tm	SP_PSW+1(%r15),0x01	# returning to user ?
-	bno	BASED(sysc_restore)
 	tm	__TI_flags+3(%r9),_TIF_WORK_SVC
 	bnz	BASED(sysc_work)  # there is work to do (signals etc.)
 sysc_restore:
@@ -312,6 +310,8 @@
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+	tm	SP_PSW+1(%r15),0x01	# returning to user ?
+	bno	BASED(sysc_restore)
 	tm	__TI_flags+3(%r9),_TIF_MCCK_PENDING
 	bo	BASED(sysc_mcck_pending)
 	tm	__TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -602,12 +602,6 @@
 	la	%r2,SP_PTREGS(%r15)	# address of register-save area
 	basr	%r14,%r1		# branch to standard irq handler
 io_return:
-	tm	SP_PSW+1(%r15),0x01	# returning to user ?
-#ifdef CONFIG_PREEMPT
-	bno	BASED(io_preempt)	# no -> check for preemptive scheduling
-#else
-	bno	BASED(io_restore)	# no-> skip resched & signal
-#endif
 	tm	__TI_flags+3(%r9),_TIF_WORK_INT
 	bnz	BASED(io_work)		# there is work to do (signals etc.)
 io_restore:
@@ -629,10 +623,18 @@
 	.long	0, io_restore_trace + 0x80000000
 #endif
 
-#ifdef CONFIG_PREEMPT
-io_preempt:
+#
+# switch to kernel stack, then check the TIF bits
+#
+io_work:
+	tm	SP_PSW+1(%r15),0x01	# returning to user ?
+#ifndef CONFIG_PREEMPT
+	bno	BASED(io_restore)	# no-> skip resched & signal
+#else
+	bnz	BASED(io_work_user)	# no -> check for preemptive scheduling
+	# check for preemptive scheduling
 	icm	%r0,15,__TI_precount(%r9)
-	bnz	BASED(io_restore)
+	bnz	BASED(io_restore)	# preemption disabled
 	l	%r1,SP_R15(%r15)
 	s	%r1,BASED(.Lc_spsize)
 	mvc	SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -646,10 +648,7 @@
 	br	%r1			# call schedule
 #endif
 
-#
-# switch to kernel stack, then check the TIF bits
-#
-io_work:
+io_work_user:
 	l	%r1,__LC_KERNEL_STACK
 	s	%r1,BASED(.Lc_spsize)
 	mvc	SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 5a4a7bc..fee1017 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -271,8 +271,6 @@
 	stg	%r2,SP_R2(%r15) # store return value (change R2 on stack)
 
 sysc_return:
-	tm	SP_PSW+1(%r15),0x01	# returning to user ?
-	jno	sysc_restore
 	tm	__TI_flags+7(%r9),_TIF_WORK_SVC
 	jnz	sysc_work	# there is work to do (signals etc.)
 sysc_restore:
@@ -304,6 +302,8 @@
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+	tm	SP_PSW+1(%r15),0x01	# returning to user ?
+	jno	sysc_restore
 	tm	__TI_flags+7(%r9),_TIF_MCCK_PENDING
 	jo	sysc_mcck_pending
 	tm	__TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -585,12 +585,6 @@
 	la	%r2,SP_PTREGS(%r15)	# address of register-save area
 	brasl	%r14,do_IRQ		# call standard irq handler
 io_return:
-	tm	SP_PSW+1(%r15),0x01	# returning to user ?
-#ifdef CONFIG_PREEMPT
-	jno	io_preempt		# no -> check for preemptive scheduling
-#else
-	jno	io_restore		# no-> skip resched & signal
-#endif
 	tm	__TI_flags+7(%r9),_TIF_WORK_INT
 	jnz	io_work 		# there is work to do (signals etc.)
 io_restore:
@@ -612,10 +606,41 @@
 	.quad	0, io_restore_trace
 #endif
 
-#ifdef CONFIG_PREEMPT
-io_preempt:
+#
+# There is work todo, we need to check if we return to userspace, then
+# check, if we are in SIE, if yes leave it
+#
+io_work:
+	tm	SP_PSW+1(%r15),0x01	# returning to user ?
+#ifndef CONFIG_PREEMPT
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+	jnz	io_work_user		# yes -> no need to check for SIE
+	la	%r1, BASED(sie_opcode)	# we return to kernel here
+	lg	%r2, SP_PSW+8(%r15)
+	clc	0(2,%r1), 0(%r2)	# is current instruction = SIE?
+	jne	io_restore		# no-> return to kernel
+	lg	%r1, SP_PSW+8(%r15)	# yes-> add 4 bytes to leave SIE
+	aghi	%r1, 4
+	stg	%r1, SP_PSW+8(%r15)
+	j	io_restore		# return to kernel
+#else
+	jno	io_restore		# no-> skip resched & signal
+#endif
+#else
+	jnz	io_work_user		# yes -> do resched & signal
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+	la	%r1, BASED(sie_opcode)
+	lg	%r2, SP_PSW+8(%r15)
+	clc	0(2,%r1), 0(%r2)	# is current instruction = SIE?
+	jne	0f			# no -> leave PSW alone
+	lg	%r1, SP_PSW+8(%r15)	# yes-> add 4 bytes to leave SIE
+	aghi	%r1, 4
+	stg	%r1, SP_PSW+8(%r15)
+0:
+#endif
+	# check for preemptive scheduling
 	icm	%r0,15,__TI_precount(%r9)
-	jnz	io_restore
+	jnz	io_restore		# preemption is disabled
 	# switch to kernel stack
 	lg	%r1,SP_R15(%r15)
 	aghi	%r1,-SP_SIZE
@@ -629,10 +654,7 @@
 	jg	preempt_schedule_irq
 #endif
 
-#
-# switch to kernel stack, then check TIF bits
-#
-io_work:
+io_work_user:
 	lg	%r1,__LC_KERNEL_STACK
 	aghi	%r1,-SP_SIZE
 	mvc	SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -653,6 +675,11 @@
 	j	io_restore
 io_work_done:
 
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+sie_opcode:
+	.long 0xb2140000
+#endif
+
 #
 # _TIF_MCCK_PENDING is set, call handler
 #
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 7f42701..35827b9 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -292,8 +292,7 @@
 	return 0;
 }
 
-static int
-do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	ptrace_area parea; 
 	int copied, ret;
@@ -529,35 +528,19 @@
 	return 0;
 }
 
-static int
-do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+			compat_ulong_t caddr, compat_ulong_t cdata)
 {
-	unsigned int tmp;  /* 4 bytes !! */
+	unsigned long addr = caddr;
+	unsigned long data = cdata;
 	ptrace_area_emu31 parea; 
 	int copied, ret;
 
 	switch (request) {
-	case PTRACE_PEEKTEXT:
-	case PTRACE_PEEKDATA:
-		/* read word at location addr. */
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-		if (copied != sizeof(tmp))
-			return -EIO;
-		return put_user(tmp, (unsigned int __force __user *) data);
-
 	case PTRACE_PEEKUSR:
 		/* read the word at location addr in the USER area. */
 		return peek_user_emu31(child, addr, data);
 
-	case PTRACE_POKETEXT:
-	case PTRACE_POKEDATA:
-		/* write the word at location addr. */
-		tmp = data;
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
-		if (copied != sizeof(tmp))
-			return -EIO;
-		return 0;
-
 	case PTRACE_POKEUSR:
 		/* write the word at location addr in the USER area */
 		return poke_user_emu31(child, addr, data);
@@ -587,82 +570,11 @@
 			copied += sizeof(unsigned int);
 		}
 		return 0;
-	case PTRACE_GETEVENTMSG:
-		return put_user((__u32) child->ptrace_message,
-				(unsigned int __force __user *) data);
-	case PTRACE_GETSIGINFO:
-		if (child->last_siginfo == NULL)
-			return -EINVAL;
-		return copy_siginfo_to_user32((compat_siginfo_t
-					       __force __user *) data,
-					      child->last_siginfo);
-	case PTRACE_SETSIGINFO:
-		if (child->last_siginfo == NULL)
-			return -EINVAL;
-		return copy_siginfo_from_user32(child->last_siginfo,
-						(compat_siginfo_t
-						 __force __user *) data);
 	}
-	return ptrace_request(child, request, addr, data);
+	return compat_ptrace_request(child, request, addr, data);
 }
 #endif
 
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
-{
-	switch (request) {
-	case PTRACE_SYSCALL:
-		/* continue and stop at next (return from) syscall */
-	case PTRACE_CONT:
-		/* restart after signal. */
-		if (!valid_signal(data))
-			return -EIO;
-		if (request == PTRACE_SYSCALL)
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		else
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		/* make sure the single step bit is not set. */
-		user_disable_single_step(child);
-		wake_up_process(child);
-		return 0;
-
-	case PTRACE_KILL:
-		/*
-		 * make the child exit.  Best I can do is send it a sigkill. 
-		 * perhaps it should be put in the status that it wants to 
-		 * exit.
-		 */
-		if (child->exit_state == EXIT_ZOMBIE) /* already dead */
-			return 0;
-		child->exit_code = SIGKILL;
-		/* make sure the single step bit is not set. */
-		user_disable_single_step(child);
-		wake_up_process(child);
-		return 0;
-
-	case PTRACE_SINGLESTEP:
-		/* set the trap flag. */
-		if (!valid_signal(data))
-			return -EIO;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		user_enable_single_step(child);
-		/* give it a chance to run. */
-		wake_up_process(child);
-		return 0;
-
-	/* Do requests that differ for 31/64 bit */
-	default:
-#ifdef CONFIG_COMPAT
-		if (test_thread_flag(TIF_31BIT))
-			return do_ptrace_emu31(child, request, addr, data);
-#endif
-		return do_ptrace_normal(child, request, addr, data);
-	}
-	/* Not reached.  */
-	return -EIO;
-}
-
 asmlinkage void
 syscall_trace(struct pt_regs *regs, int entryexit)
 {
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 1761b74..e051cad 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -22,7 +22,6 @@
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
 	select S390_SWITCH_AMODE
-	select PREEMPT
 	---help---
 	  Support hosting paravirtualized guest machines using the SIE
 	  virtualization capability on the mainframe. This should work
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 349581a..47a0b64 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -105,6 +105,9 @@
 static int handle_noop(struct kvm_vcpu *vcpu)
 {
 	switch (vcpu->arch.sie_block->icptcode) {
+	case 0x0:
+		vcpu->stat.exit_null++;
+		break;
 	case 0x10:
 		vcpu->stat.exit_external_request++;
 		break;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 98d1e73..0ac36a6 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -31,6 +31,7 @@
 
 struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ "userspace_handled", VCPU_STAT(exit_userspace) },
+	{ "exit_null", VCPU_STAT(exit_null) },
 	{ "exit_validity", VCPU_STAT(exit_validity) },
 	{ "exit_stop_request", VCPU_STAT(exit_stop_request) },
 	{ "exit_external_request", VCPU_STAT(exit_external_request) },
@@ -221,10 +222,6 @@
 	vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
 	restore_fp_regs(&vcpu->arch.guest_fpregs);
 	restore_access_regs(vcpu->arch.guest_acrs);
-
-	if (signal_pending(current))
-		atomic_set_mask(CPUSTAT_STOP_INT,
-			&vcpu->arch.sie_block->cpuflags);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index fb988a4..2a74581 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -5,3 +5,4 @@
 obj-y	 := init.o fault.o extmem.o mmap.o vmem.o pgtable.o
 obj-$(CONFIG_CMM) += cmm.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_PAGE_STATES) += page-states.o
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index fa31de6..29f3a63 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -126,6 +126,9 @@
         /* clear the zero-page */
         memset(empty_zero_page, 0, PAGE_SIZE);
 
+	/* Setup guest page hinting */
+	cmma_init();
+
 	/* this will put all low memory onto the freelists */
 	totalram_pages += free_all_bootmem();
 
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c
new file mode 100644
index 0000000..fc0ad73
--- /dev/null
+++ b/arch/s390/mm/page-states.c
@@ -0,0 +1,79 @@
+/*
+ * arch/s390/mm/page-states.c
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * Guest page hinting for unused pages.
+ *
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#define ESSA_SET_STABLE		1
+#define ESSA_SET_UNUSED		2
+
+static int cmma_flag;
+
+static int __init cmma(char *str)
+{
+	char *parm;
+	parm = strstrip(str);
+	if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) {
+		cmma_flag = 1;
+		return 1;
+	}
+	cmma_flag = 0;
+	if (strcmp(parm, "no") == 0 || strcmp(parm, "off") == 0)
+		return 1;
+	return 0;
+}
+
+__setup("cmma=", cmma);
+
+void __init cmma_init(void)
+{
+	register unsigned long tmp asm("0") = 0;
+	register int rc asm("1") = -EOPNOTSUPP;
+
+	if (!cmma_flag)
+		return;
+	asm volatile(
+		"       .insn rrf,0xb9ab0000,%1,%1,0,0\n"
+		"0:     la      %0,0\n"
+		"1:\n"
+		EX_TABLE(0b,1b)
+		: "+&d" (rc), "+&d" (tmp));
+	if (rc)
+		cmma_flag = 0;
+}
+
+void arch_free_page(struct page *page, int order)
+{
+	int i, rc;
+
+	if (!cmma_flag)
+		return;
+	for (i = 0; i < (1 << order); i++)
+		asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
+			     : "=&d" (rc)
+			     : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT),
+			       "i" (ESSA_SET_UNUSED));
+}
+
+void arch_alloc_page(struct page *page, int order)
+{
+	int i, rc;
+
+	if (!cmma_flag)
+		return;
+	for (i = 0; i < (1 << order); i++)
+		asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
+			     : "=&d" (rc)
+			     : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT),
+			       "i" (ESSA_SET_STABLE));
+}
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 6a679c3..8a68160 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -448,14 +448,6 @@
 	  Select Dreamcast if configuring for a SEGA Dreamcast.
 	  More information at <http://www.linux-sh.org>
 
-config SH_MPC1211
-	bool "Interface MPC1211"
-	depends on CPU_SUBTYPE_SH7751 && BROKEN
-	help
-	  CTP/PCI-SH02 is a CPU module computer that is produced
-	  by Interface Corporation.
-	  More information at <http://www.interface.co.jp>
-
 config SH_SH03
 	bool "Interface CTP/PCI-SH03"
 	depends on CPU_SUBTYPE_SH7751
@@ -657,8 +649,7 @@
 endmenu
 
 config ISA_DMA_API
-	def_bool y
-	depends on SH_MPC1211
+	bool
 
 menu "Kernel features"
 
@@ -666,7 +657,7 @@
 
 config KEXEC
 	bool "kexec system call (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	depends on SUPERH32 && EXPERIMENTAL
 	help
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
@@ -683,7 +674,7 @@
 
 config CRASH_DUMP
 	bool "kernel crash dumps (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	depends on SUPERH32 && EXPERIMENTAL
 	help
 	  Generate crash dump after being started by kexec.
 	  This should be normally only set in special crash dump kernels
@@ -763,7 +754,7 @@
 
 config ZERO_PAGE_OFFSET
 	hex "Zero page offset"
-	default "0x00004000" if SH_MPC1211 || SH_SH03
+	default "0x00004000" if SH_SH03
 	default "0x00010000" if PAGE_SIZE_64KB
 	default "0x00002000" if PAGE_SIZE_8KB
 	default "0x00001000"
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index d9d28f9..0d2ef1e 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -7,6 +7,7 @@
 
 config SH_STANDARD_BIOS
 	bool "Use LinuxSH standard BIOS"
+	depends on SUPERH32
 	help
 	  Say Y here if your target has the gdb-sh-stub
 	  package from www.m17n.org (or any conforming standard LinuxSH BIOS)
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index bb06f83..8050b03 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -110,7 +110,6 @@
 machdir-$(CONFIG_SH_7721_SOLUTION_ENGINE)	+= se/7721
 machdir-$(CONFIG_SH_HP6XX)			+= hp6xx
 machdir-$(CONFIG_SH_DREAMCAST)			+= dreamcast
-machdir-$(CONFIG_SH_MPC1211)			+= mpc1211
 machdir-$(CONFIG_SH_SH03)			+= sh03
 machdir-$(CONFIG_SH_SECUREEDGE5410)		+= snapgear
 machdir-$(CONFIG_SH_RTS7751R2D)			+= renesas/rts7751r2d
diff --git a/arch/sh/boards/mpc1211/Makefile b/arch/sh/boards/mpc1211/Makefile
deleted file mode 100644
index 8cd31b5..0000000
--- a/arch/sh/boards/mpc1211/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for the Interface (CTP/PCI/MPC-SH02) specific parts of the kernel
-#
-
-obj-y	 := setup.o rtc.o
-
-obj-$(CONFIG_PCI) += pci.o
-
diff --git a/arch/sh/boards/mpc1211/pci.c b/arch/sh/boards/mpc1211/pci.c
deleted file mode 100644
index 23849f7..0000000
--- a/arch/sh/boards/mpc1211/pci.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- *	Low-Level PCI Support for the MPC-1211(CTP/PCI/MPC-SH02)
- *
- *  (c) 2002-2003 Saito.K & Jeanne
- *
- *  Dustin McIntire (dustin@sensoria.com)
- *	Derived from arch/i386/kernel/pci-*.c which bore the message:
- *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
- *	
- *  May be copied or modified under the terms of the GNU General Public
- *  License.  See linux/COPYING for more information.
- *
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-
-#include <asm/machvec.h>
-#include <asm/io.h>
-#include <asm/mpc1211/pci.h>
-
-static struct resource mpcpci_io_resource = {
-	"MPCPCI IO",
-	0x00000000,
-	0xffffffff,
-	IORESOURCE_IO
-};
-
-static struct resource mpcpci_mem_resource = {
-	"MPCPCI mem",
-	0x00000000,
-	0xffffffff,
-	IORESOURCE_MEM
-};
-
-static struct pci_ops pci_direct_conf1;
-struct pci_channel board_pci_channels[] = {
-	{&pci_direct_conf1, &mpcpci_io_resource, &mpcpci_mem_resource, 0, 256},
-	{NULL, NULL, NULL, 0, 0},
-};
-
-/*
- * Direct access to PCI hardware...
- */
-
-
-#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
-
-/*
- * Functions for accessing PCI configuration space with type 1 accesses
- */
-static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
-	u32 word;
-	unsigned long flags;
-
-	/* 
-	 * PCIPDR may only be accessed as 32 bit words, 
-	 * so we must do byte alignment by hand 
-	 */
-	local_irq_save(flags);
-	writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
-	word = readl(PCIPDR);
-	local_irq_restore(flags);
-
-	switch (size) {
-	case 1:
-		switch (where & 0x3) {
-		case 3:
-			*value = (u8)(word >> 24);
-			break;
-		case 2:
-			*value = (u8)(word >> 16);
-			break;
-		case 1:
-			*value = (u8)(word >> 8);
-			break;
-		default:
-			*value = (u8)word;
-			break;
-		}
-		break;
-	case 2:
-		switch (where & 0x3) {
-		case 3:
-			*value = (u16)(word >> 24);
-			local_irq_save(flags);
-			writel(CONFIG_CMD(bus,devfn,(where+1)), PCIPAR);
-			word = readl(PCIPDR);
-			local_irq_restore(flags);
-			*value |= ((word & 0xff) << 8);
-			break;
-		case 2:
-			*value = (u16)(word >> 16);
-			break;
-		case 1:
-			*value = (u16)(word >> 8);
-			break;
-		default:
-			*value = (u16)word;
-			break;
-		}
-		break;
-	case 4:
-		*value = word;
-		break;
-	}
-	PCIDBG(4,"pci_conf1_read@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),*value); 
-	return PCIBIOS_SUCCESSFUL;    
-}
-
-/* 
- * Since MPC-1211 only does 32bit access we'll have to do a read,mask,write operation.  
- * We'll allow an odd byte offset, though it should be illegal.
- */ 
-static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
-	u32 word,mask = 0;
-	unsigned long flags;
-	u32 shift = (where & 3) * 8;
-
-	if(size == 1) {
-		mask = ((1 << 8) - 1) << shift;  // create the byte mask
-	} else if(size == 2){
-		if(shift == 24)
-			return PCIBIOS_BAD_REGISTER_NUMBER;           
-		mask = ((1 << 16) - 1) << shift;  // create the word mask
-	}
-	local_irq_save(flags);
-	writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
-	if(size == 4){
-		writel(value, PCIPDR);
-		local_irq_restore(flags);
-		PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),value);
-		return PCIBIOS_SUCCESSFUL;
-	}
-	word = readl(PCIPDR);
-	word &= ~mask;
-	word |= ((value << shift) & mask);
-	writel(word, PCIPDR);
-	local_irq_restore(flags);
-	PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),word);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-#undef CONFIG_CMD
-
-static struct pci_ops pci_direct_conf1 = {
-	.read =		pci_conf1_read,
-	.write = 	pci_conf1_write,
-};
-
-static void __devinit quirk_ali_ide_ports(struct pci_dev *dev)
-{
-        dev->resource[0].start = 0x1f0;
-	dev->resource[0].end   = 0x1f7;
-	dev->resource[0].flags = IORESOURCE_IO;
-        dev->resource[1].start = 0x3f6;
-	dev->resource[1].end   = 0x3f6;
-	dev->resource[1].flags = IORESOURCE_IO;
-        dev->resource[2].start = 0x170;
-	dev->resource[2].end   = 0x177;
-	dev->resource[2].flags = IORESOURCE_IO;
-        dev->resource[3].start = 0x376;
-	dev->resource[3].end   = 0x376;
-	dev->resource[3].flags = IORESOURCE_IO;
-        dev->resource[4].start = 0xf000;
-	dev->resource[4].end   = 0xf00f;
-	dev->resource[4].flags = IORESOURCE_IO;
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_ports);
-
-char * __devinit pcibios_setup(char *str)
-{
-	return str;
-}
-
-/*
- *  Called after each bus is probed, but before its children
- *  are examined.
- */
-
-void __devinit pcibios_fixup_bus(struct pci_bus *b)
-{
-	pci_read_bridge_bases(b);
-}
-
-/* 
- * 	IRQ functions 
- */
-static inline u8 bridge_swizzle(u8 pin, u8 slot)
-{
-        return (((pin-1) + slot) % 4) + 1;
-}
-
-static inline u8 bridge_swizzle_pci_1(u8 pin, u8 slot)
-{
-        return (((pin-1) - slot) & 3) + 1;
-}
-
-static u8 __init mpc1211_swizzle(struct pci_dev *dev, u8 *pinp)
-{
-	unsigned long flags;
-        u8 pin = *pinp;
-	u32 word;
-
-	for ( ; dev->bus->self; dev = dev->bus->self) {
-		if (!pin)
-			continue;
-
-		if (dev->bus->number == 1) {
-			local_irq_save(flags);
-			writel(0x80000000 | 0x2c, PCIPAR);
-			word = readl(PCIPDR);
-			local_irq_restore(flags);
-			word >>= 16;
-
-			if (word == 0x0001)
-				pin = bridge_swizzle_pci_1(pin, PCI_SLOT(dev->devfn));
-			else
-				pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
-		} else
-			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
-	}
-
-	*pinp = pin;
-
-	return PCI_SLOT(dev->devfn);
-}
-
-static int __init map_mpc1211_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-	int irq = -1;
-
-	/* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
-	if (dev->bus->number == 0) {
-		switch (slot) {
-		case 13:   irq =  9; break;   /* USB */
-		case 22:   irq = 10; break;   /* LAN */
-		default:   irq =  0; break;
-	  	}
-	} else {
-		switch (pin) {
-		case 0:   irq =  0; break;
-		case 1:   irq =  7; break;
-		case 2:   irq =  9; break;
-		case 3:   irq = 10; break;
-		case 4:   irq = 11; break;
-		}
-	}
-
-	if( irq < 0 ) {
-		PCIDBG(3, "PCI: Error mapping IRQ on device %s\n", pci_name(dev));
-		return irq;
-	}
-	
-	PCIDBG(2, "Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
-
-	return irq;
-}
-
-void __init pcibios_fixup_irqs(void)
-{
-	pci_fixup_irqs(mpc1211_swizzle, map_mpc1211_irq);
-}
-
-void pcibios_align_resource(void *data, struct resource *res,
-			    resource_size_t size, resource_size_t align)
-{
-	resource_size_t start = res->start;
-
-	if (res->flags & IORESOURCE_IO) {
-		if (start >= 0x10000UL) {
-			if ((start & 0xffffUL) < 0x4000UL) {
-				start = (start & 0xffff0000UL) + 0x4000UL;
-			} else if ((start & 0xffffUL) >= 0xf000UL) {
-				start = (start & 0xffff0000UL) + 0x10000UL;
-			}
-			res->start = start;
-		} else {
-			if (start & 0x300) {
-				start = (start + 0x3ff) & ~0x3ff;
-				res->start = start;
-			}
-		}
-	}
-}
-
diff --git a/arch/sh/boards/mpc1211/rtc.c b/arch/sh/boards/mpc1211/rtc.c
deleted file mode 100644
index 03b123a..0000000
--- a/arch/sh/boards/mpc1211/rtc.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * linux/arch/sh/kernel/rtc-mpc1211.c -- MPC-1211 on-chip RTC support
- *
- *  Copyright (C) 2002  Saito.K & Jeanne
- *
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/bcd.h>
-#include <linux/mc146818rtc.h>
-
-unsigned long get_cmos_time(void)
-{
-	unsigned int year, mon, day, hour, min, sec;
-
-	spin_lock(&rtc_lock);
-
-	do {
-		sec = CMOS_READ(RTC_SECONDS);
-		min = CMOS_READ(RTC_MINUTES);
-		hour = CMOS_READ(RTC_HOURS);
-		day = CMOS_READ(RTC_DAY_OF_MONTH);
-		mon = CMOS_READ(RTC_MONTH);
-		year = CMOS_READ(RTC_YEAR);
-	} while (sec != CMOS_READ(RTC_SECONDS));
-
-	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		BCD_TO_BIN(sec);
-		BCD_TO_BIN(min);
-		BCD_TO_BIN(hour);
-		BCD_TO_BIN(day);
-		BCD_TO_BIN(mon);
-		BCD_TO_BIN(year);
-	}
-
-	spin_unlock(&rtc_lock);
-
-	year += 1900;
-	if (year < 1970)
-		year += 100;
-
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-void mpc1211_rtc_gettimeofday(struct timeval *tv)
-{
-
-	tv->tv_sec = get_cmos_time();
-	tv->tv_usec = 0;
-}
-
-/* arc/i386/kernel/time.c */
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you'll only notice that after reboot!
- */
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-
-	/* gets recalled with irq locally disabled */
-	spin_lock(&rtc_lock);
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-		BCD_TO_BIN(cmos_minutes);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-			BIN_TO_BCD(real_seconds);
-			BIN_TO_BCD(real_minutes);
-		}
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
-		retval = -1;
-	}
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...                           -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-	spin_unlock(&rtc_lock);
-
-	return retval;
-}
-
-int mpc1211_rtc_settimeofday(const struct timeval *tv)
-{
-	unsigned long nowtime = tv->tv_sec;
-
-	return set_rtc_mmss(nowtime);
-}
-
-void mpc1211_time_init(void)
-{
-	rtc_sh_get_time = mpc1211_rtc_gettimeofday;
-	rtc_sh_set_time = mpc1211_rtc_settimeofday;
-}
-
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c
deleted file mode 100644
index fede363..0000000
--- a/arch/sh/boards/mpc1211/setup.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * linux/arch/sh/boards/mpc1211/setup.c
- *
- * Copyright (C) 2002  Saito.K & Jeanne,  Fujii.Y
- *
- */
-
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <asm/io.h>
-#include <asm/machvec.h>
-#include <asm/mpc1211/mpc1211.h>
-#include <asm/mpc1211/pci.h>
-#include <asm/mpc1211/m1543c.h>
-
-/* ALI15X3 SMBus address offsets */
-#define SMBHSTSTS   (0 + 0x3100)
-#define SMBHSTCNT   (1 + 0x3100)
-#define SMBHSTSTART (2 + 0x3100)
-#define SMBHSTCMD   (7 + 0x3100)
-#define SMBHSTADD   (3 + 0x3100)
-#define SMBHSTDAT0  (4 + 0x3100)
-#define SMBHSTDAT1  (5 + 0x3100)
-#define SMBBLKDAT   (6 + 0x3100)
-
-/* Other settings */
-#define MAX_TIMEOUT 500		/* times 1/100 sec */
-
-/* ALI15X3 command constants */
-#define ALI15X3_ABORT      0x04
-#define ALI15X3_T_OUT      0x08
-#define ALI15X3_QUICK      0x00
-#define ALI15X3_BYTE       0x10
-#define ALI15X3_BYTE_DATA  0x20
-#define ALI15X3_WORD_DATA  0x30
-#define ALI15X3_BLOCK_DATA 0x40
-#define ALI15X3_BLOCK_CLR  0x80
-
-/* ALI15X3 status register bits */
-#define ALI15X3_STS_IDLE	0x04
-#define ALI15X3_STS_BUSY	0x08
-#define ALI15X3_STS_DONE	0x10
-#define ALI15X3_STS_DEV		0x20	/* device error */
-#define ALI15X3_STS_COLL	0x40	/* collision or no response */
-#define ALI15X3_STS_TERM	0x80	/* terminated by abort */
-#define ALI15X3_STS_ERR		0xE0	/* all the bad error bits */
-
-static void __init pci_write_config(unsigned long busNo,
-				    unsigned long devNo,
-				    unsigned long fncNo,
-				    unsigned long cnfAdd,
-				    unsigned long cnfData)
-{
-	ctrl_outl((0x80000000 
-                + ((busNo & 0xff) << 16) 
-                + ((devNo & 0x1f) << 11) 
-                + ((fncNo & 0x07) <<  8) 
-		+ (cnfAdd & 0xfc)), PCIPAR);
-
-        ctrl_outl(cnfData, PCIPDR);
-}
-
-/*
-  Initialize IRQ setting
-*/
-
-static unsigned char m_irq_mask = 0xfb;
-static unsigned char s_irq_mask = 0xff;
-
-static void disable_mpc1211_irq(unsigned int irq)
-{
-	if( irq < 8) {
-		m_irq_mask |= (1 << irq);
-		outb(m_irq_mask,I8259_M_MR);
-	} else {
-		s_irq_mask |= (1 << (irq - 8));
-		outb(s_irq_mask,I8259_S_MR);
-	}
-
-}
-
-static void enable_mpc1211_irq(unsigned int irq)
-{
-	if( irq < 8) {
-		m_irq_mask &= ~(1 << irq);
-		outb(m_irq_mask,I8259_M_MR);
-	} else {
-		s_irq_mask &= ~(1 << (irq - 8));
-		outb(s_irq_mask,I8259_S_MR);
-	}
-}
-
-static inline int mpc1211_irq_real(unsigned int irq)
-{
-	int value;
-	int irqmask;
-
-	if ( irq < 8) {
-		irqmask = 1<<irq;
-		outb(0x0b,I8259_M_CR);		/* ISR register */
-		value = inb(I8259_M_CR) & irqmask;
-		outb(0x0a,I8259_M_CR);		/* back ro the IPR reg */
-		return value;
-	}
-	irqmask = 1<<(irq - 8);
-	outb(0x0b,I8259_S_CR);		/* ISR register */
-	value = inb(I8259_S_CR) & irqmask;
-	outb(0x0a,I8259_S_CR);		/* back ro the IPR reg */
-	return value;
-}
-
-static void mask_and_ack_mpc1211(unsigned int irq)
-{
-	if(irq < 8) {
-		if(m_irq_mask & (1<<irq)){
-		  if(!mpc1211_irq_real(irq)){
-		    atomic_inc(&irq_err_count)
-		    printk("spurious 8259A interrupt: IRQ %x\n",irq);
-		   }
-		} else {
-			m_irq_mask |= (1<<irq);
-		}
-		inb(I8259_M_MR);		/* DUMMY */
-		outb(m_irq_mask,I8259_M_MR);	/* disable */
-		outb(0x60+irq,I8259_M_CR);	/* EOI */
-		
-	} else {
-		if(s_irq_mask & (1<<(irq - 8))){
-		  if(!mpc1211_irq_real(irq)){
-		    atomic_inc(&irq_err_count);
-		    printk("spurious 8259A interrupt: IRQ %x\n",irq);
-		  }
-		} else {
-			s_irq_mask |= (1<<(irq - 8));
-		}
-		inb(I8259_S_MR);		/* DUMMY */
-		outb(s_irq_mask,I8259_S_MR);	/* disable */
-		outb(0x60+(irq-8),I8259_S_CR); 	/* EOI */
-		outb(0x60+2,I8259_M_CR);
-	}
-}
-
-static void end_mpc1211_irq(unsigned int irq)
-{
-	enable_mpc1211_irq(irq);
-}
-
-static unsigned int startup_mpc1211_irq(unsigned int irq)
-{
-	enable_mpc1211_irq(irq);
-	return 0;
-}
-
-static void shutdown_mpc1211_irq(unsigned int irq)
-{
-	disable_mpc1211_irq(irq);
-}
-
-static struct hw_interrupt_type mpc1211_irq_type = {
-	.typename	= "MPC1211-IRQ",
-	.startup	= startup_mpc1211_irq,
-	.shutdown	= shutdown_mpc1211_irq,
-	.enable		= enable_mpc1211_irq,
-	.disable	= disable_mpc1211_irq,
-	.ack		= mask_and_ack_mpc1211,
-	.end		= end_mpc1211_irq
-};
-
-static void make_mpc1211_irq(unsigned int irq)
-{
-	irq_desc[irq].chip = &mpc1211_irq_type;
-	irq_desc[irq].status  = IRQ_DISABLED;
-	irq_desc[irq].action  = 0;
-	irq_desc[irq].depth   = 1;
-	disable_mpc1211_irq(irq);
-}
-
-int mpc1211_irq_demux(int irq)
-{
-	unsigned int poll;
-
-	if( irq == 2 ) {
-		outb(0x0c,I8259_M_CR);
-		poll = inb(I8259_M_CR);
-		if(poll & 0x80) {
-			irq = (poll & 0x07);
-		}
-		if( irq == 2) {
-			outb(0x0c,I8259_S_CR);
-			poll = inb(I8259_S_CR);
-			irq = (poll & 0x07) + 8;
-		}
-	}
-	return irq;
-}
-
-static void __init init_mpc1211_IRQ(void)
-{
-	int i;
-	/*
-	 * Super I/O (Just mimic PC):
-	 *  1: keyboard
-	 *  3: serial 1
-	 *  4: serial 0
-	 *  5: printer
-	 *  6: floppy
-	 *  8: rtc
-	 * 10: lan
-	 * 12: mouse
-	 * 14: ide0
-	 * 15: ide1
-	 */
-
-	pci_write_config(0,0,0,0x54, 0xb0b0002d);
-	outb(0x11, I8259_M_CR); 	/* mater icw1 edge trigger  */
-	outb(0x11, I8259_S_CR);		/* slave icw1 edge trigger  */
-	outb(0x20, I8259_M_MR); 	/* m icw2 base vec 0x08	    */
-	outb(0x28, I8259_S_MR);		/* s icw2 base vec 0x70	    */
-	outb(0x04, I8259_M_MR);		/* m icw3 slave irq2	    */
-	outb(0x02, I8259_S_MR);		/* s icw3 slave id	    */
-	outb(0x01, I8259_M_MR);		/* m icw4 non buf normal eoi*/
-	outb(0x01, I8259_S_MR);		/* s icw4 non buf normal eo1*/
-	outb(0xfb, I8259_M_MR);		/* disable irq0--irq7  */
-	outb(0xff, I8259_S_MR);		/* disable irq8--irq15 */
-
-	for ( i=0; i < 16; i++) {
-		if(i != 2) {
-			make_mpc1211_irq(i);
-		}
-	}
-}
-
-static void delay1000(void)
-{
-	int i;
-
-	for (i=0; i<1000; i++)
-		ctrl_delay();
-}
-
-static int put_smb_blk(unsigned char *p, int address, int command, int no)
-{
-	int temp;
-	int timeout;
-	int i;
-
-	outb(0xff, SMBHSTSTS);
-	temp = inb(SMBHSTSTS);
-	for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++) {
-		delay1000();
-		temp = inb(SMBHSTSTS);
-	}
-	if (timeout >= MAX_TIMEOUT){
-		return -1;
-	}
-
-	outb(((address & 0x7f) << 1), SMBHSTADD);
-	outb(0xc0, SMBHSTCNT);
-	outb(command & 0xff, SMBHSTCMD);
-	outb(no & 0x1f, SMBHSTDAT0);
-
-	for(i = 1; i <= no; i++) {
-		outb(*p++, SMBBLKDAT);
-	}
-	outb(0xff, SMBHSTSTART);
-
-	temp = inb(SMBHSTSTS);
-	for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) {
-		delay1000();
-		temp = inb(SMBHSTSTS);
-	}
-	if (timeout >= MAX_TIMEOUT) {
-		return -2;
-	}
-	if ( temp & ALI15X3_STS_ERR ){
-		return -3;
-	}
-	return 0;
-}
-
-static struct resource heartbeat_resources[] = {
-	[0] = {
-		.start	= 0xa2000000,
-		.end	= 0xa2000000,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device heartbeat_device = {
-	.name		= "heartbeat",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(heartbeat_resources),
-	.resource	= heartbeat_resources,
-};
-
-static struct platform_device *mpc1211_devices[] __initdata = {
-	&heartbeat_device,
-};
-
-static int __init mpc1211_devices_setup(void)
-{
-	return platform_add_devices(mpc1211_devices,
-				    ARRAY_SIZE(mpc1211_devices));
-}
-__initcall(mpc1211_devices_setup);
-
-/* arch/sh/boards/mpc1211/rtc.c */
-void mpc1211_time_init(void);
-
-static void __init mpc1211_setup(char **cmdline_p)
-{
-	unsigned char spd_buf[128];
-
-	__set_io_port_base(PA_PCI_IO);
-
-	pci_write_config(0,0,0,0x54, 0xb0b00000);
-
-	do {
-		outb(ALI15X3_ABORT, SMBHSTCNT);
-		spd_buf[0] = 0x0c;
-		spd_buf[1] = 0x43;
-		spd_buf[2] = 0x7f;
-		spd_buf[3] = 0x03;
-		spd_buf[4] = 0x00;
-		spd_buf[5] = 0x03;
-		spd_buf[6] = 0x00;
-	} while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0);
-
-	board_time_init = mpc1211_time_init;
-
-	return 0;
-}
-
-/*
- * The Machine Vector
- */
-static struct sh_machine_vector mv_mpc1211 __initmv = {
-	.mv_name		= "Interface MPC-1211(CTP/PCI/MPC-SH02)",
-	.mv_setup		= mpc1211_setup,
-	.mv_nr_irqs		= 48,
-	.mv_irq_demux		= mpc1211_irq_demux,
-	.mv_init_irq		= init_mpc1211_IRQ,
-};
diff --git a/arch/sh/boards/renesas/migor/setup.c b/arch/sh/boards/renesas/migor/setup.c
index e7c150d..01af442 100644
--- a/arch/sh/boards/renesas/migor/setup.c
+++ b/arch/sh/boards/renesas/migor/setup.c
@@ -14,6 +14,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
 #include <linux/i2c.h>
+#include <linux/smc91x.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
 #include <asm/sh_keysc.h>
@@ -27,6 +28,11 @@
  * 0x18000000       8GB    8   NAND Flash (K9K8G08U0A)
  */
 
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT,
+	.irq_flags = IRQF_TRIGGER_HIGH,
+};
+
 static struct resource smc91x_eth_resources[] = {
 	[0] = {
 		.name   = "SMC91C111" ,
@@ -36,7 +42,7 @@
 	},
 	[1] = {
 		.start  = 32, /* IRQ0 */
-		.flags  = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+		.flags  = IORESOURCE_IRQ,
 	},
 };
 
@@ -44,6 +50,9 @@
 	.name           = "smc91x",
 	.num_resources  = ARRAY_SIZE(smc91x_eth_resources),
 	.resource       = smc91x_eth_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 
 static struct sh_keysc_info sh_keysc_info = {
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c
index 68f0ad1..ae1cfcb 100644
--- a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c
@@ -62,7 +62,7 @@
 static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors,
 			 NULL, mask_registers, NULL, NULL);
 
-unsigned char * __init highlander_init_irq_r7780mp(void)
+unsigned char * __init highlander_plat_irq_setup(void)
 {
 	if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) {
 		printk(KERN_INFO "Using r7780mp interrupt controller.\n");
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
index bd34048..9d3921f 100644
--- a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
@@ -55,7 +55,7 @@
 static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors,
 			 NULL, mask_registers, NULL, NULL);
 
-unsigned char * __init highlander_init_irq_r7780rp(void)
+unsigned char * __init highlander_plat_irq_setup(void)
 {
 	if (ctrl_inw(0xa5000600)) {
 		printk(KERN_INFO "Using r7780rp interrupt controller.\n");
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
index bf7ec10..896c045 100644
--- a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
@@ -64,7 +64,7 @@
 static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors,
 			 NULL, mask_registers, NULL, NULL);
 
-unsigned char * __init highlander_init_irq_r7785rp(void)
+unsigned char * __init highlander_plat_irq_setup(void)
 {
 	if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000)
 		return NULL;
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index ac0a965..bc79afb 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -316,7 +316,7 @@
 
 static unsigned char irl2irq[HL_NR_IRL];
 
-int highlander_irq_demux(int irq)
+static int highlander_irq_demux(int irq)
 {
 	if (irq >= HL_NR_IRL || !irl2irq[irq])
 		return irq;
@@ -324,27 +324,9 @@
 	return irl2irq[irq];
 }
 
-void __init highlander_init_irq(void)
+static void __init highlander_init_irq(void)
 {
-	unsigned char *ucp = NULL;
-
-	do {
-#ifdef CONFIG_SH_R7780MP
-		ucp = highlander_init_irq_r7780mp();
-		if (ucp)
-			break;
-#endif
-#ifdef CONFIG_SH_R7785RP
-		ucp = highlander_init_irq_r7785rp();
-		if (ucp)
-			break;
-#endif
-#ifdef CONFIG_SH_R7780RP
-		ucp = highlander_init_irq_r7780rp();
-		if (ucp)
-			break;
-#endif
-	} while (0);
+	unsigned char *ucp = highlander_plat_irq_setup();
 
 	if (ucp) {
 		plat_irq_setup_pins(IRQ_MODE_IRL3210);
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index f21ee49..452d0d6 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -109,7 +109,6 @@
 	.resource	= heartbeat_resources,
 };
 
-#ifdef CONFIG_MFD_SM501
 static struct plat_serial8250_port uart_platform_data[] = {
 	{
 		.membase	= (void __iomem *)0xb3e30000,
@@ -208,13 +207,9 @@
 	.resource	= sm501_resources,
 };
 
-#endif /* CONFIG_MFD_SM501 */
-
 static struct platform_device *rts7751r2d_devices[] __initdata = {
-#ifdef CONFIG_MFD_SM501
 	&uart_device,
 	&sm501_device,
-#endif
 	&heartbeat_device,
 	&spi_sh_sci_device,
 };
@@ -234,7 +229,9 @@
 {
 	if (register_trapped_io(&cf_trapped_io) == 0)
 		platform_device_register(&cf_ide_device);
+
 	spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
+
 	return platform_add_devices(rts7751r2d_devices,
 				    ARRAY_SIZE(rts7751r2d_devices));
 }
diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c
index 5b3ee08..4fe84cc 100644
--- a/arch/sh/boards/se/7206/setup.c
+++ b/arch/sh/boards/se/7206/setup.c
@@ -3,12 +3,13 @@
  * linux/arch/sh/boards/se/7206/setup.c
  *
  * Copyright (C) 2006  Yoshinori Sato
- * Copyright (C) 2007  Paul Mundt
+ * Copyright (C) 2007 - 2008  Paul Mundt
  *
  * Hitachi 7206 SolutionEngine Support.
  */
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/smc91x.h>
 #include <asm/se7206.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
@@ -16,8 +17,9 @@
 
 static struct resource smc91x_resources[] = {
 	[0] = {
-		.start		= 0x300,
-		.end		= 0x300 + 0x020 - 1,
+		.name		= "smc91x-regs",
+		.start		= PA_SMSC + 0x300,
+		.end		= PA_SMSC + 0x300 + 0x020 - 1,
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -27,9 +29,18 @@
 	},
 };
 
+static struct smc91x_platdata smc91x_info = {
+	.flags	= SMC91X_USE_16BIT,
+};
+
 static struct platform_device smc91x_device = {
 	.name		= "smc91x",
 	.id		= -1,
+	.dev		= {
+		.dma_mask		= NULL,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &smc91x_info,
+	},
 	.num_resources	= ARRAY_SIZE(smc91x_resources),
 	.resource	= smc91x_resources,
 };
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c
index 33f6ee7..ede3957 100644
--- a/arch/sh/boards/se/7722/setup.c
+++ b/arch/sh/boards/se/7722/setup.c
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/input.h>
+#include <linux/smc91x.h>
 #include <asm/machvec.h>
 #include <asm/se7722.h>
 #include <asm/io.h>
@@ -44,6 +45,10 @@
 };
 
 /* SMC91x */
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT,
+};
+
 static struct resource smc91x_eth_resources[] = {
 	[0] = {
 		.name   = "smc91x-regs" ,
@@ -64,6 +69,7 @@
 	.dev = {
 		.dma_mask               = NULL,         /* don't use dma */
 		.coherent_dma_mask      = 0xffffffff,
+		.platform_data	= &smc91x_info,
 	},
 	.num_resources  = ARRAY_SIZE(smc91x_eth_resources),
 	.resource       = smc91x_eth_resources,
diff --git a/arch/sh/boot/compressed/Makefile_32 b/arch/sh/boot/compressed/Makefile_32
index 6ac8d4a..c0d25fb 100644
--- a/arch/sh/boot/compressed/Makefile_32
+++ b/arch/sh/boot/compressed/Makefile_32
@@ -6,7 +6,6 @@
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz \
 		   head_32.o misc_32.o piggy.o
-EXTRA_AFLAGS	:= -traditional
 
 OBJECTS = $(obj)/head_32.o $(obj)/misc_32.o
 
diff --git a/arch/sh/boot/compressed/Makefile_64 b/arch/sh/boot/compressed/Makefile_64
index 4334f2b..912f3e2 100644
--- a/arch/sh/boot/compressed/Makefile_64
+++ b/arch/sh/boot/compressed/Makefile_64
@@ -13,7 +13,6 @@
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz \
 		   head_64.o misc_64.o cache.o piggy.o
-EXTRA_AFLAGS	:= -traditional
 
 OBJECTS		:= $(obj)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o \
 		   $(obj)/cache.o
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index d6e0e2b..de45c6a 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -184,9 +184,8 @@
 
 void __init plat_irq_setup(void)
 {
-        unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
+	unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
 	unsigned long reg;
-	unsigned long data;
 	int i;
 
 	intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
@@ -196,11 +195,8 @@
 
 
 	/* Set default: per-line enable/disable, priority driven ack/eoi */
-	for (i = 0; i < NR_INTC_IRQS; i++) {
-		if (platform_int_priority[i] != NO_PRIORITY) {
-			irq_desc[i].chip = &intc_irq_type;
-		}
-	}
+	for (i = 0; i < NR_INTC_IRQS; i++)
+		irq_desc[i].chip = &intc_irq_type;
 
 
 	/* Disable all interrupts and set all priorities to 0 to avoid trouble */
@@ -211,35 +207,42 @@
 		ctrl_outl( NO_PRIORITY, reg);
 
 
-	/* Set IRLM */
-	/* If all the priorities are set to 'no priority', then
-	 * assume we are using encoded mode.
-	 */
-	irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \
-		platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3];
+#ifdef CONFIG_SH_CAYMAN
+	{
+		unsigned long data;
 
-	if (irlm == NO_PRIORITY) {
-		/* IRLM = 0 */
-		reg = INTC_ICR_CLEAR;
-		i = IRQ_INTA;
-		printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
-	} else {
-		/* IRLM = 1 */
-		reg = INTC_ICR_SET;
-		i = IRQ_IRL0;
-	}
-	ctrl_outl(INTC_ICR_IRLM, reg);
-
-	/* Set interrupt priorities according to platform description */
-	for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
-		data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4);
-		if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
-			/* Upon the 7th, set Priority Register */
-			ctrl_outl(data, reg);
-			data = 0;
-			reg += 8;
+		/* Set IRLM */
+		/* If all the priorities are set to 'no priority', then
+		 * assume we are using encoded mode.
+		 */
+		irlm = platform_int_priority[IRQ_IRL0] +
+		       platform_int_priority[IRQ_IRL1] +
+		       platform_int_priority[IRQ_IRL2] +
+		       platform_int_priority[IRQ_IRL3];
+		if (irlm == NO_PRIORITY) {
+			/* IRLM = 0 */
+			reg = INTC_ICR_CLEAR;
+			i = IRQ_INTA;
+			printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
+		} else {
+			/* IRLM = 1 */
+			reg = INTC_ICR_SET;
+			i = IRQ_IRL0;
 		}
-	}
+		ctrl_outl(INTC_ICR_IRLM, reg);
+
+		/* Set interrupt priorities according to platform description */
+		for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
+			data |= platform_int_priority[i] <<
+				((i % INTC_INTPRI_PPREG) * 4);
+			if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
+				/* Upon the 7th, set Priority Register */
+				ctrl_outl(data, reg);
+				data = 0;
+				reg += 8;
+			}
+		}
+#endif
 
 	/*
 	 * And now let interrupts come in.
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c
index 84806b2..da5dae7 100644
--- a/arch/sh/kernel/cpu/irq/intc.c
+++ b/arch/sh/kernel/cpu/irq/intc.c
@@ -1,7 +1,7 @@
 /*
  * Shared interrupt handling code for IPR and INTC2 types of IRQs.
  *
- * Copyright (C) 2007 Magnus Damm
+ * Copyright (C) 2007, 2008 Magnus Damm
  *
  * Based on intc2.c and ipr.c
  *
@@ -62,6 +62,9 @@
 #endif
 
 static unsigned int intc_prio_level[NR_IRQS]; /* for now */
+#ifdef CONFIG_CPU_SH3
+static unsigned long ack_handle[NR_IRQS];
+#endif
 
 static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
 {
@@ -98,17 +101,26 @@
 
 static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
 {
+	unsigned long flags;
+	local_irq_save(flags);
 	ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
+	local_irq_restore(flags);
 }
 
 static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
 {
+	unsigned long flags;
+	local_irq_save(flags);
 	ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
+	local_irq_restore(flags);
 }
 
 static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
 {
+	unsigned long flags;
+	local_irq_save(flags);
 	ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
+	local_irq_restore(flags);
 }
 
 enum {	REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };
@@ -219,6 +231,25 @@
 	}
 }
 
+#ifdef CONFIG_CPU_SH3
+static void intc_mask_ack(unsigned int irq)
+{
+	struct intc_desc_int *d = get_intc_desc(irq);
+	unsigned long handle = ack_handle[irq];
+	unsigned long addr;
+
+	intc_disable(irq);
+
+	/* read register and write zero only to the assocaited bit */
+
+	if (handle) {
+		addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+		ctrl_inb(addr);
+		ctrl_outb(0x3f ^ set_field(0, 1, handle), addr);
+	}
+}
+#endif
+
 static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
 					     unsigned int nr_hp,
 					     unsigned int irq)
@@ -280,7 +311,12 @@
 	[IRQ_TYPE_EDGE_FALLING] = VALID(0),
 	[IRQ_TYPE_EDGE_RISING] = VALID(1),
 	[IRQ_TYPE_LEVEL_LOW] = VALID(2),
+	/* SH7706, SH7707 and SH7709 do not support high level triggered */
+#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \
+    !defined(CONFIG_CPU_SUBTYPE_SH7707) && \
+    !defined(CONFIG_CPU_SUBTYPE_SH7709)
 	[IRQ_TYPE_LEVEL_HIGH] = VALID(3),
+#endif
 };
 
 static int intc_set_sense(unsigned int irq, unsigned int type)
@@ -430,6 +466,40 @@
 	return 0;
 }
 
+#ifdef CONFIG_CPU_SH3
+static unsigned int __init intc_ack_data(struct intc_desc *desc,
+					  struct intc_desc_int *d,
+					  intc_enum enum_id)
+{
+	struct intc_mask_reg *mr = desc->ack_regs;
+	unsigned int i, j, fn, mode;
+	unsigned long reg_e, reg_d;
+
+	for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) {
+		mr = desc->ack_regs + i;
+
+		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
+			if (mr->enum_ids[j] != enum_id)
+				continue;
+
+			fn = REG_FN_MODIFY_BASE;
+			mode = MODE_ENABLE_REG;
+			reg_e = mr->set_reg;
+			reg_d = mr->set_reg;
+
+			fn += (mr->reg_width >> 3) - 1;
+			return _INTC_MK(fn, mode,
+					intc_get_reg(d, reg_e),
+					intc_get_reg(d, reg_d),
+					1,
+					(mr->reg_width - 1) - j);
+		}
+	}
+
+	return 0;
+}
+#endif
+
 static unsigned int __init intc_sense_data(struct intc_desc *desc,
 					   struct intc_desc_int *d,
 					   intc_enum enum_id)
@@ -530,6 +600,11 @@
 
 	/* irq should be disabled by default */
 	d->chip.mask(irq);
+
+#ifdef CONFIG_CPU_SH3
+	if (desc->ack_regs)
+		ack_handle[irq] = intc_ack_data(desc, d, enum_id);
+#endif
 }
 
 static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -560,6 +635,9 @@
 	d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
 	d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
 
+#ifdef CONFIG_CPU_SH3
+	d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
+#endif
 	d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
 #ifdef CONFIG_SMP
 	d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp));
@@ -592,14 +670,23 @@
 		}
 	}
 
-	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
-
 	d->chip.name = desc->name;
 	d->chip.mask = intc_disable;
 	d->chip.unmask = intc_enable;
 	d->chip.mask_ack = intc_disable;
 	d->chip.set_type = intc_set_sense;
 
+#ifdef CONFIG_CPU_SH3
+	if (desc->ack_regs) {
+		for (i = 0; i < desc->nr_ack_regs; i++)
+			k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
+
+		d->chip.mask_ack = intc_mask_ack;
+	}
+#endif
+
+	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
+
 	for (i = 0; i < desc->nr_vectors; i++) {
 		struct intc_vect *vect = desc->vectors + i;
 
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
index 5627c0b..6df2fb9 100644
--- a/arch/sh/kernel/cpu/sh2a/fpu.c
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -300,7 +300,7 @@
 		iy = hy & 0x7fffffff;
 		if (iy < 0x00800000) {
 			ix = denormal_subf1(ix, iy);
-			if (ix < 0) {
+			if ((int) ix < 0) {
 				ix = -ix;
 				sign ^= 0x80000000;
 			}
@@ -385,7 +385,7 @@
 		iy = hy & 0x7fffffffffffffffLL;
 		if (iy < 0x0010000000000000LL) {
 			ix = denormal_subd1(ix, iy);
-			if (ix < 0) {
+			if ((int) ix < 0) {
 				ix = -ix;
 				sign ^= 0x8000000000000000LL;
 			}
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index 3ae4d91..511de55 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the Linux/SuperH SH-3 backends.
 #
 
-obj-y	:= ex.o probe.o entry.o
+obj-y	:= ex.o probe.o entry.o setup-sh3.o
 
 # CPU subtype setup
 obj-$(CONFIG_CPU_SUBTYPE_SH7705)	+= setup-sh7705.o
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c
new file mode 100644
index 0000000..c988468
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c
@@ -0,0 +1,71 @@
+/*
+ * Shared SH3 Setup code
+ *
+ *  Copyright (C) 2008  Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+/* All SH3 devices are equipped with IRQ0->5 (except sh7708) */
+
+enum {
+	UNUSED = 0,
+
+	/* interrupt sources */
+	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
+};
+
+static struct intc_vect vectors_irq0123[] __initdata = {
+	INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
+	INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
+};
+
+static struct intc_vect vectors_irq45[] __initdata = {
+	INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+	{ 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
+	{ 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+	{ 0xa4000004, 0, 8, /* IRR0 */
+	  { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+	{ 0xa4000010, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh3-irq0123",
+			     vectors_irq0123, NULL, NULL,
+			     prio_registers, sense_registers, ack_registers);
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45",
+			     vectors_irq45, NULL, NULL,
+			     prio_registers, sense_registers, ack_registers);
+
+#define INTC_ICR1		0xa4000010UL
+#define INTC_ICR1_IRQLVL	(1<<14)
+
+void __init plat_irq_setup_pins(int mode)
+{
+	if (mode == IRQ_MODE_IRQ) {
+		ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
+		register_intc_controller(&intc_desc_irq0123);
+		return;
+	}
+	BUG();
+}
+
+void __init plat_irq_setup_sh3(void)
+{
+	register_intc_controller(&intc_desc_irq45);
+}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index f581534..6468ae8 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -37,7 +37,7 @@
 };
 
 static struct intc_vect vectors[] __initdata = {
-	INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+	/* IRQ0->5 are handled in setup-sh3.c */
 	INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
 	INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
 	INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
@@ -48,7 +48,7 @@
 	INTC_VECT(ADC_ADI, 0x980),
 	INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40),
 	INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20),
-	INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0),
+	INTC_VECT(TPU2, 0xc80), INTC_VECT(TPU3, 0xca0),
 	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
 	INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
 	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
@@ -81,14 +81,6 @@
 static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
 			 NULL, prio_registers, NULL);
 
-static struct intc_vect vectors_irq[] __initdata = {
-	INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-	INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL,
-			 NULL, prio_registers, NULL);
-
 static struct plat_sci_port sci_platform_data[] = {
 	{
 		.mapbase	= 0xa4410000,
@@ -159,16 +151,8 @@
 }
 __initcall(sh7705_devices_setup);
 
-void __init plat_irq_setup_pins(int mode)
-{
-	if (mode == IRQ_MODE_IRQ) {
-		register_intc_controller(&intc_desc_irq);
-		return;
-	}
-	BUG();
-}
-
 void __init plat_irq_setup(void)
 {
 	register_intc_controller(&intc_desc);
+	plat_irq_setup_sh3();
 }
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index d3733b1..93c55e2 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -52,7 +52,7 @@
 #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7707) || \
     defined(CONFIG_CPU_SUBTYPE_SH7709)
-	INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+	/* IRQ0->5 are handled in setup-sh3.c */
 	INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
 	INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
 	INTC_VECT(ADC_ADI, 0x980),
@@ -104,18 +104,6 @@
 static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
 			 NULL, prio_registers, NULL);
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-static struct intc_vect vectors_irq[] __initdata = {
-	INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-	INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL,
-			 NULL, prio_registers, NULL);
-#endif
-
 static struct resource rtc_resources[] = {
 	[0] =	{
 		.start	= 0xfffffec0,
@@ -194,24 +182,12 @@
 }
 __initcall(sh770x_devices_setup);
 
-#define INTC_ICR1		0xa4000010UL
-#define INTC_ICR1_IRQLVL	(1<<14)
-
-void __init plat_irq_setup_pins(int mode)
-{
-	if (mode == IRQ_MODE_IRQ) {
-#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-		ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
-		register_intc_controller(&intc_desc_irq);
-		return;
-#endif
-	}
-	BUG();
-}
-
 void __init plat_irq_setup(void)
 {
 	register_intc_controller(&intc_desc);
+#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
+	plat_irq_setup_sh3();
+#endif
 }
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 7406c9a..77eee48 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -38,7 +38,7 @@
 };
 
 static struct intc_vect vectors[] __initdata = {
-	INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
+	/* IRQ0->5 are handled in setup-sh3.c */
 	INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
 	INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
 	INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
@@ -79,10 +79,7 @@
 	{ 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
 	{ 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
 	{ 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } },
-	{ 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } },
-#ifdef CONFIG_CPU_SUBTYPE_SH7710
-	{ 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } },
-#endif
+	{ 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC, DMAC2 } },
 	{ 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } },
 	{ 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } },
 	{ 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } },
@@ -91,14 +88,6 @@
 static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
 			 NULL, prio_registers, NULL);
 
-static struct intc_vect vectors_irq[] __initdata = {
-	INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-	INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-};
-
-static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL,
-			 NULL, prio_registers, NULL);
-
 static struct resource rtc_resources[] = {
 	[0] =	{
 		.start	= 0xa413fec0,
@@ -170,16 +159,8 @@
 }
 __initcall(sh7710_devices_setup);
 
-void __init plat_irq_setup_pins(int mode)
-{
-	if (mode == IRQ_MODE_IRQ) {
-		register_intc_controller(&intc_desc_irq);
-		return;
-	}
-	BUG();
-}
-
 void __init plat_irq_setup(void)
 {
 	register_intc_controller(&intc_desc);
+	plat_irq_setup_sh3();
 }
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 8028082..f807a21 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -19,10 +19,6 @@
 #include <linux/serial_sci.h>
 #include <asm/rtc.h>
 
-#define INTC_ICR1	0xA4140010UL
-#define INTC_ICR_IRLM   0x4000
-#define INTC_ICR_IRQ	(~INTC_ICR_IRLM)
-
 static struct resource rtc_resources[] = {
 	[0] = {
 		.start	= 0xa413fec0,
@@ -170,6 +166,7 @@
 };
 
 static struct intc_vect vectors[] __initdata = {
+	/* IRQ0->5 are handled in setup-sh3.c */
 	INTC_VECT(TMU0, 0x400),       INTC_VECT(TMU1, 0x420),
 	INTC_VECT(TMU2, 0x440),       INTC_VECT(RTC_ATI, 0x480),
 	INTC_VECT(RTC_PRI, 0x4a0),    INTC_VECT(RTC_CUI, 0x4c0),
@@ -214,11 +211,7 @@
 	{ 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
 	{ 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
 	{ 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } },
-#if defined(CONFIG_CPU_SUBTYPE_SH7720)
 	{ 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } },
-#else
-	{ 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, 0 } },
-#endif
 	{ 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } },
 	{ 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } },
 	{ 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } },
@@ -229,32 +222,8 @@
 static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
 		NULL, prio_registers, NULL);
 
-static struct intc_sense_reg sense_registers[] __initdata = {
-	{ INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
-};
-
-static struct intc_vect vectors_irq[] __initdata = {
-	INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
-	INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
-	INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
-};
-
-static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq,
-		NULL, NULL, prio_registers, sense_registers);
-
-void __init plat_irq_setup_pins(int mode)
-{
-	switch (mode) {
-	case IRQ_MODE_IRQ:
-		ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1);
-		register_intc_controller(&intc_irq_desc);
-		break;
-	default:
-		BUG();
-	}
-}
-
 void __init plat_irq_setup(void)
 {
 	register_intc_controller(&intc_desc);
+	plat_irq_setup_sh3();
 }
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index ba87501..05372ed 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -143,12 +143,22 @@
 trap_jtable:
 	.long	do_exception_error		/* 0x000 */
 	.long	do_exception_error		/* 0x020 */
+#ifdef CONFIG_MMU
 	.long	tlb_miss_load				/* 0x040 */
 	.long	tlb_miss_store				/* 0x060 */
+#else
+	.long	do_exception_error
+	.long	do_exception_error
+#endif
 	! ARTIFICIAL pseudo-EXPEVT setting
 	.long	do_debug_interrupt		/* 0x080 */
+#ifdef CONFIG_MMU
 	.long	tlb_miss_load				/* 0x0A0 */
 	.long	tlb_miss_store				/* 0x0C0 */
+#else
+	.long	do_exception_error
+	.long	do_exception_error
+#endif
 	.long	do_address_error_load	/* 0x0E0 */
 	.long	do_address_error_store	/* 0x100 */
 #ifdef CONFIG_SH_FPU
@@ -185,10 +195,18 @@
 	.endr
 	.long	do_IRQ			/* 0xA00 */
 	.long	do_IRQ			/* 0xA20 */
+#ifdef CONFIG_MMU
 	.long	itlb_miss_or_IRQ			/* 0xA40 */
+#else
+	.long	do_IRQ
+#endif
 	.long	do_IRQ			/* 0xA60 */
 	.long	do_IRQ			/* 0xA80 */
+#ifdef CONFIG_MMU
 	.long	itlb_miss_or_IRQ			/* 0xAA0 */
+#else
+	.long	do_IRQ
+#endif
 	.long	do_exception_error		/* 0xAC0 */
 	.long	do_address_error_exec	/* 0xAE0 */
 	.rept 8
@@ -274,6 +292,7 @@
 	 * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
 	 * block making sure the final alignment is correct.
 	 */
+#ifdef CONFIG_MMU
 tlb_miss:
 	synco	/* TAKum03020 (but probably a good idea anyway.) */
 	putcon	SP, KCR1
@@ -377,6 +396,9 @@
 	getcon	KCR1, SP
 	pta	handle_exception, tr0
 	blink	tr0, ZERO
+#else /* CONFIG_MMU */
+	.balign 256
+#endif
 
 /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
    DOES END UP AT VBR+0x600 */
@@ -1103,6 +1125,7 @@
  * fpu_error_or_IRQ? is a helper to deflect to the right cause.
  *
  */
+#ifdef CONFIG_MMU
 tlb_miss_load:
 	or	SP, ZERO, r2
 	or	ZERO, ZERO, r3		/* Read */
@@ -1132,6 +1155,7 @@
 	movi	do_page_fault, r6
         ptabs	r6, tr0
         blink	tr0, ZERO
+#endif /* CONFIG_MMU */
 
 fpu_error_or_IRQA:
 	pta	its_IRQ, tr0
@@ -1481,6 +1505,7 @@
 	ptabs	LINK, tr0
 	blink	tr0, r63
 
+#ifdef CONFIG_MMU
 /*
  * --- User Access Handling Section
  */
@@ -1604,6 +1629,7 @@
 	ptabs	LINK, tr0
 	blink	tr0, ZERO
 
+#endif /* CONFIG_MMU */
 
 /*
  * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
@@ -2014,9 +2040,11 @@
 	.global asm_uaccess_start	/* Just a marker */
 asm_uaccess_start:
 
+#ifdef CONFIG_MMU
 	.long	___copy_user1, ___copy_user_exit
 	.long	___copy_user2, ___copy_user_exit
 	.long	___clear_user1, ___clear_user_exit
+#endif
 	.long	___strncpy_from_user1, ___strncpy_from_user_exit
 	.long	___strnlen_user1, ___strnlen_user_exit
 	.long	___get_user_asm_b1, ___get_user_asm_b_exit
diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c
index 31f8cb0..92ad844 100644
--- a/arch/sh/kernel/cpu/sh5/probe.c
+++ b/arch/sh/kernel/cpu/sh5/probe.c
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <asm/processor.h>
 #include <asm/cache.h>
+#include <asm/tlb.h>
 
 int __init detect_cpu_and_cache_system(void)
 {
@@ -67,5 +68,8 @@
 	set_bit(SH_CACHE_MODE_WB, &(boot_cpu_data.dcache.flags));
 #endif
 
+	/* Setup some I/D TLB defaults */
+	sh64_tlb_init();
+
 	return 0;
 }
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 957f2561..6b7d166 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -141,7 +141,9 @@
  */
 static void scif_sercon_init(char *s)
 {
+	struct uart_port *port = &scif_port;
 	unsigned baud = DEFAULT_BAUD;
+	unsigned int status;
 	char *e;
 
 	if (*s == ',')
@@ -160,19 +162,25 @@
 			baud = DEFAULT_BAUD;
 	}
 
-	ctrl_outw(0, scif_port.mapbase + 8);
-	ctrl_outw(0, scif_port.mapbase);
+	do {
+		status = sci_in(port, SCxSR);
+	} while (!(status & SCxSR_TEND(port)));
+
+	sci_out(port, SCSCR, 0);	 /* TE=0, RE=0 */
+	sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+	sci_out(port, SCSMR, 0);
 
 	/* Set baud rate */
-	ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) /
-		  (32 * baud) - 1, scif_port.mapbase + 4);
+	sci_out(port, SCBRR, (CONFIG_SH_PCLK_FREQ + 16 * baud) /
+		(32 * baud) - 1);
+	udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
 
-	ctrl_outw(12, scif_port.mapbase + 24);
-	ctrl_outw(8, scif_port.mapbase + 24);
-	ctrl_outw(0, scif_port.mapbase + 32);
-	ctrl_outw(0x60, scif_port.mapbase + 16);
-	ctrl_outw(0, scif_port.mapbase + 36);
-	ctrl_outw(0x30, scif_port.mapbase + 8);
+	sci_out(port, SCSPTR, 0);
+	sci_out(port, SCxSR, 0x60);
+	sci_out(port, SCLSR, 0);
+
+	sci_out(port, SCFCR, 0);
+	sci_out(port, SCSCR, 0x30);	 /* TE=1, RE=1 */
 }
 #endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */
 #endif /* !defined(CONFIG_SH_STANDARD_BIOS) */
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index d453c3a..832641bb 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -330,14 +330,6 @@
 	return mem;
 }
 
-/* Pack a hex byte */
-static char *pack_hex_byte(char *pkt, int byte)
-{
-	*pkt++ = hexchars[(byte >> 4) & 0xf];
-	*pkt++ = hexchars[(byte & 0xf)];
-	return pkt;
-}
-
 /* Scan for the start char '$', read the packet and check the checksum */
 static void get_packet(char *buffer, int buflen)
 {
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 284f66f..516bde9 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -53,6 +53,7 @@
  * sh_mv= on the command line, prior to .machvec.init teardown.
  */
 struct sh_machine_vector sh_mv = { .mv_name = "generic", };
+EXPORT_SYMBOL(sh_mv);
 
 #ifdef CONFIG_VT
 struct screen_info screen_info;
@@ -76,11 +77,18 @@
 	.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
 };
 
+static struct resource bss_resource = {
+	.name	= "Kernel bss",
+	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM,
+};
+
 unsigned long memory_start;
 EXPORT_SYMBOL(memory_start);
 unsigned long memory_end = 0;
 EXPORT_SYMBOL(memory_end);
 
+static struct resource mem_resources[MAX_NUMNODES];
+
 int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
 
 static int __init early_parse_mem(char *p)
@@ -169,6 +177,40 @@
 {}
 #endif
 
+void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
+						unsigned long end_pfn)
+{
+	struct resource *res = &mem_resources[nid];
+
+	WARN_ON(res->name); /* max one active range per node for now */
+
+	res->name = "System RAM";
+	res->start = start_pfn << PAGE_SHIFT;
+	res->end = (end_pfn << PAGE_SHIFT) - 1;
+	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	if (request_resource(&iomem_resource, res)) {
+		pr_err("unable to request memory_resource 0x%lx 0x%lx\n",
+		       start_pfn, end_pfn);
+		return;
+	}
+
+	/*
+	 *  We don't know which RAM region contains kernel data,
+	 *  so we try it repeatedly and let the resource manager
+	 *  test it.
+	 */
+	request_resource(res, &code_resource);
+	request_resource(res, &data_resource);
+	request_resource(res, &bss_resource);
+
+#ifdef CONFIG_KEXEC
+	if (crashk_res.start != crashk_res.end)
+		request_resource(res, &crashk_res);
+#endif
+
+	add_active_range(nid, start_pfn, end_pfn);
+}
+
 void __init setup_bootmem_allocator(unsigned long free_pfn)
 {
 	unsigned long bootmap_size;
@@ -181,7 +223,7 @@
 	bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
 					 min_low_pfn, max_low_pfn);
 
-	add_active_range(0, min_low_pfn, max_low_pfn);
+	__add_active_range(0, min_low_pfn, max_low_pfn);
 	register_bootmem_low_pages();
 
 	node_set_online(0);
@@ -267,6 +309,8 @@
 	code_resource.end = virt_to_phys(_etext)-1;
 	data_resource.start = virt_to_phys(_etext);
 	data_resource.end = virt_to_phys(_edata)-1;
+	bss_resource.start = virt_to_phys(__bss_start);
+	bss_resource.end = virt_to_phys(_ebss)-1;
 
 	memory_start = (unsigned long)__va(__MEMORY_START);
 	if (!memory_end)
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 6d40546..8f91653 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -20,8 +20,6 @@
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 extern struct hw_interrupt_type no_irq_type;
 
-EXPORT_SYMBOL(sh_mv);
-
 /* platform dependent support */
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(kernel_thread);
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index a310c97..9324d32 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -16,6 +16,7 @@
 #include <linux/in6.h>
 #include <linux/interrupt.h>
 #include <linux/screen_info.h>
+#include <asm/cacheflush.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/checksum.h>
@@ -29,25 +30,50 @@
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(kernel_thread);
 
+#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU)
+EXPORT_SYMBOL(clear_user_page);
+#endif
+
+#ifndef CONFIG_CACHE_OFF
+EXPORT_SYMBOL(flush_dcache_page);
+#endif
+
 /* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_nocheck);
+#ifdef CONFIG_IPV6
+EXPORT_SYMBOL(csum_ipv6_magic);
+#endif
 
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
 
+EXPORT_SYMBOL(__put_user_asm_b);
+EXPORT_SYMBOL(__put_user_asm_w);
 EXPORT_SYMBOL(__put_user_asm_l);
+EXPORT_SYMBOL(__put_user_asm_q);
+EXPORT_SYMBOL(__get_user_asm_b);
+EXPORT_SYMBOL(__get_user_asm_w);
 EXPORT_SYMBOL(__get_user_asm_l);
+EXPORT_SYMBOL(__get_user_asm_q);
+EXPORT_SYMBOL(__strnlen_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__copy_user);
 EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
+EXPORT_SYMBOL(__const_udelay);
 
 /* Ugh.  These come in from libgcc.a at link time. */
 #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
 
 DECLARE_EXPORT(__sdivsi3);
+DECLARE_EXPORT(__sdivsi3_2);
 DECLARE_EXPORT(__muldi3);
 DECLARE_EXPORT(__udivsi3);
+DECLARE_EXPORT(__div_table);
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index 898977e..022a55f 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -172,6 +172,7 @@
 	tv->tv_sec = sec;
 	tv->tv_usec = usec;
 }
+EXPORT_SYMBOL(do_gettimeofday);
 
 int do_settimeofday(struct timespec *tv)
 {
@@ -240,7 +241,7 @@
 	 * the irq version of write_lock because as just said we have irq
 	 * locally disabled. -arca
 	 */
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 	asm ("getcon cr62, %0" : "=r" (current_ctc));
 	ctc_last_interrupt = (unsigned long) current_ctc;
 
@@ -266,7 +267,7 @@
 			/* do it again in 60 s */
 			last_rtc_update = xtime.tv_sec - 600;
 	}
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 
 #ifndef CONFIG_SMP
 	update_process_times(user_mode(get_irq_regs()));
diff --git a/arch/sh/lib64/dbg.c b/arch/sh/lib64/dbg.c
index 75825ef..2fb8eaf 100644
--- a/arch/sh/lib64/dbg.c
+++ b/arch/sh/lib64/dbg.c
@@ -186,8 +186,8 @@
 	rr->pc = regs->pc;
 
 	if (sp < stack_bottom + 3092) {
-		printk("evt_debug : stack underflow report\n");
 		int i, j;
+		printk("evt_debug : stack underflow report\n");
 		for (j=0, i = event_ptr; j<16; j++) {
 			rr = event_ring + i;
 			printk("evt=%08x event=%08x tra=%08x pid=%5d sp=%08lx pc=%08lx\n",
diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64
index cbd6aa3..0d92a8a 100644
--- a/arch/sh/mm/Makefile_64
+++ b/arch/sh/mm/Makefile_64
@@ -2,10 +2,11 @@
 # Makefile for the Linux SuperH-specific parts of the memory manager.
 #
 
-obj-y			:= init.o extable_64.o consistent.o
+obj-y			:= init.o consistent.o
 
-mmu-y			:= tlb-nommu.o pg-nommu.o
-mmu-$(CONFIG_MMU)	:= fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o
+mmu-y			:= tlb-nommu.o pg-nommu.o extable_32.o
+mmu-$(CONFIG_MMU)	:= fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \
+			   extable_64.o
 
 ifndef CONFIG_CACHE_OFF
 obj-y			+= cache-sh5.o
diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c
index 3877321..9e277ec 100644
--- a/arch/sh/mm/cache-sh5.c
+++ b/arch/sh/mm/cache-sh5.c
@@ -714,6 +714,7 @@
 	sh64_icache_inv_current_user_range(vaddr, end);
 }
 
+#ifdef CONFIG_MMU
 /*
  * These *MUST* lie in an area of virtual address space that's otherwise
  * unused.
@@ -830,3 +831,4 @@
 	else
 		sh64_clear_user_page_coloured(to, address);
 }
+#endif
diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c
index cea224c..6e0be24 100644
--- a/arch/sh/mm/ioremap_64.c
+++ b/arch/sh/mm/ioremap_64.c
@@ -343,6 +343,7 @@
 
 	return shmedia_alloc_io(phys, size, name);
 }
+EXPORT_SYMBOL(onchip_remap);
 
 void onchip_unmap(unsigned long vaddr)
 {
@@ -370,6 +371,7 @@
 		kfree(res);
 	}
 }
+EXPORT_SYMBOL(onchip_unmap);
 
 #ifdef CONFIG_PROC_FS
 static int
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
index 2de7302..1663199 100644
--- a/arch/sh/mm/numa.c
+++ b/arch/sh/mm/numa.c
@@ -59,7 +59,7 @@
 	free_pfn = start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
 
-	add_active_range(nid, start_pfn, end_pfn);
+	__add_active_range(nid, start_pfn, end_pfn);
 
 	/* Node-local pgdat */
 	NODE_DATA(nid) = pfn_to_kaddr(free_pfn);
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 987c668..1bba7d3 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -28,7 +28,6 @@
 7751SYSTEMH		SH_7751_SYSTEMH
 HP6XX			SH_HP6XX
 DREAMCAST		SH_DREAMCAST
-MPC1211			SH_MPC1211
 SNAPGEAR		SH_SECUREEDGE5410
 EDOSK7705		SH_EDOSK7705
 SH4202_MICRODEV		SH_SH4202_MICRODEV
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 57d1bbd..4bcfe54 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1306,6 +1306,8 @@
 	.align	4
 	.globl	linux_sparc_syscall
 linux_sparc_syscall:
+	sethi	%hi(PSR_SYSCALL), %l4
+	or	%l0, %l4, %l0
 	/* Direct access to user regs, must faster. */
 	cmp	%g1, NR_SYSCALLS
 	bgeu	linux_sparc_ni_syscall
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index e7f3519..da48d24 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -419,14 +419,26 @@
                              unsigned long stack_size)
 {
 	unsigned long parent_tid_ptr, child_tid_ptr;
+	unsigned long orig_i1 = regs->u_regs[UREG_I1];
+	long ret;
 
 	parent_tid_ptr = regs->u_regs[UREG_I2];
 	child_tid_ptr = regs->u_regs[UREG_I4];
 
-	return do_fork(clone_flags, stack_start,
-		       regs, stack_size,
-		       (int __user *) parent_tid_ptr,
-		       (int __user *) child_tid_ptr);
+	ret = do_fork(clone_flags, stack_start,
+		      regs, stack_size,
+		      (int __user *) parent_tid_ptr,
+		      (int __user *) child_tid_ptr);
+
+	/* If we get an error and potentially restart the system
+	 * call, we're screwed because copy_thread() clobbered
+	 * the parent's %o1.  So detect that case and restore it
+	 * here.
+	 */
+	if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+		regs->u_regs[UREG_I1] = orig_i1;
+
+	return ret;
 }
 
 /* Copy a Sparc thread.  The fork() return value conventions
@@ -626,11 +638,6 @@
 			  (char __user * __user *)regs->u_regs[base + UREG_I2],
 			  regs);
 	putname(filename);
-	if (error == 0) {
-		task_lock(current);
-		current->ptrace &= ~PT_DTRACE;
-		task_unlock(current);
-	}
 out:
 	return error;
 }
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 7f44ae6..81f3b92 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -170,8 +170,8 @@
 		switch (pos) {
 		case 32: /* PSR */
 			psr = regs->psr;
-			psr &= ~PSR_ICC;
-			psr |= (reg & PSR_ICC);
+			psr &= ~(PSR_ICC | PSR_SYSCALL);
+			psr |= (reg & (PSR_ICC | PSR_SYSCALL));
 			regs->psr = psr;
 			break;
 		case 33: /* PC */
@@ -441,6 +441,8 @@
 		break;
 
 	default:
+		if (request == PTRACE_SPARC_DETACH)
+			request = PTRACE_DETACH;
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
index 77ca6fd..ab818cdc 100644
--- a/arch/sparc/kernel/rtrap.S
+++ b/arch/sparc/kernel/rtrap.S
@@ -50,8 +50,9 @@
 ret_trap_entry:
 ret_trap_lockless_ipi:
 	andcc	%t_psr, PSR_PS, %g0
+	sethi	%hi(PSR_SYSCALL), %g1
 	be	1f
-	 nop
+	 andn	%t_psr, %g1, %t_psr
 
 	wr	%t_psr, 0x0, %psr
 	b	ret_trap_kernel
@@ -73,7 +74,6 @@
 	 ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
 
 	mov	%l5, %o1
-	mov	%l6, %o2
 	call	do_signal
 	 add	%sp, STACKFRAME_SZ, %o0	! pt_regs ptr
 
@@ -81,6 +81,8 @@
 	ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
 	clr	%l6
 ret_trap_continue:
+	sethi	%hi(PSR_SYSCALL), %g1
+	andn	%t_psr, %g1, %t_psr
 	wr	%t_psr, 0x0, %psr
 	WRITE_PAUSE
 
@@ -137,8 +139,9 @@
 	LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
 	or	%t_pc, %t_npc, %g2
 	andcc	%g2, 0x3, %g0
+	sethi	%hi(PSR_SYSCALL), %g2
 	be	1f
-	 nop
+	 andn	%t_psr, %g2, %t_psr
 
 	b	ret_trap_unaligned_pc
 	 add	%sp, STACKFRAME_SZ, %o0
@@ -201,6 +204,8 @@
 1:
 	LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
 2:
+	sethi	%hi(PSR_SYSCALL), %twin_tmp1
+	andn	%t_psr, %twin_tmp1, %t_psr
 	wr	%t_psr, 0x0, %psr
 	WRITE_PAUSE
 
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 3c31229..3fd1df9 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -145,6 +145,9 @@
 	regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
 		  | (regs->psr & (PSR_ICC | PSR_EF));
 
+	/* Prevent syscall restart.  */
+	pt_regs_clear_syscall(regs);
+
 	err |= __get_user(fpu_save, &sf->fpu_save);
 
 	if (fpu_save)
@@ -199,6 +202,9 @@
 
 	regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
 
+	/* Prevent syscall restart.  */
+	pt_regs_clear_syscall(regs);
+
 	err |= __get_user(fpu_save, &sf->fpu_save);
 
 	if (fpu_save)
@@ -245,15 +251,29 @@
 
 static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
 {
-	unsigned long sp;
+	unsigned long sp = regs->u_regs[UREG_FP];
 
-	sp = regs->u_regs[UREG_FP];
+	/*
+	 * If we are on the alternate signal stack and would overflow it, don't.
+	 * Return an always-bogus address instead so we will die with SIGSEGV.
+	 */
+	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+		return (void __user *) -1L;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if (sa->sa_flags & SA_ONSTACK) {
-		if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
+		if (sas_ss_flags(sp) == 0)
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
+
+	/* Always align the stack frame.  This handles two cases.  First,
+	 * sigaltstack need not be mindful of platform specific stack
+	 * alignment.  Second, if we took this signal because the stack
+	 * is not aligned properly, we'd like to take the signal cleanly
+	 * and report that.
+	 */
+	sp &= ~7UL;
+
 	return (void __user *)(sp - framesize);
 }
 
@@ -493,26 +513,36 @@
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
+asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0)
 {
-	siginfo_t info;
-	struct sparc_deliver_cookie cookie;
 	struct k_sigaction ka;
-	int signr;
+	int restart_syscall;
 	sigset_t *oldset;
+	siginfo_t info;
+	int signr;
 
-	cookie.restart_syscall = restart_syscall;
-	cookie.orig_i0 = orig_i0;
+	if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
+		restart_syscall = 1;
+	else
+		restart_syscall = 0;
 
 	if (test_thread_flag(TIF_RESTORE_SIGMASK))
 		oldset = &current->saved_sigmask;
 	else
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	/* If the debugger messes with the program counter, it clears
+	 * the software "in syscall" bit, directing us to not perform
+	 * a syscall restart.
+	 */
+	if (restart_syscall && !pt_regs_is_syscall(regs))
+		restart_syscall = 0;
+
 	if (signr > 0) {
-		if (cookie.restart_syscall)
-			syscall_restart(cookie.orig_i0, regs, &ka.sa);
+		if (restart_syscall)
+			syscall_restart(orig_i0, regs, &ka.sa);
 		handle_signal(signr, &ka, &info, oldset, regs);
 
 		/* a signal was successfully delivered; the saved
@@ -524,16 +554,16 @@
 			clear_thread_flag(TIF_RESTORE_SIGMASK);
 		return;
 	}
-	if (cookie.restart_syscall &&
+	if (restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = cookie.orig_i0;
+		regs->u_regs[UREG_I0] = orig_i0;
 		regs->pc -= 4;
 		regs->npc -= 4;
 	}
-	if (cookie.restart_syscall &&
+	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->pc -= 4;
@@ -585,27 +615,3 @@
 out:
 	return ret;
 }
-
-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
-{
-	struct sparc_deliver_cookie *cp = cookie;
-
-	if (cp->restart_syscall &&
-	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = cp->orig_i0;
-		regs->pc -= 4;
-		regs->npc -= 4;
-		cp->restart_syscall = 0;
-	}
-
-	if (cp->restart_syscall &&
-	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-		regs->u_regs[UREG_G1] = __NR_restart_syscall;
-		regs->pc -= 4;
-		regs->npc -= 4;
-		cp->restart_syscall = 0;
-	}
-}
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index f188b5d..3c6b49a 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -219,12 +219,11 @@
 	return err;
 }
 
-int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
+int sparc_mmap_check(unsigned long addr, unsigned long len)
 {
 	if (ARCH_SUN4C_SUN4 &&
 	    (len > 0x20000000 ||
-	     ((flags & MAP_FIXED) &&
-	      addr < 0xe0000000 && addr + len > 0x20000000)))
+	     (addr < 0xe0000000 && addr + len > 0x20000000)))
 		return -EINVAL;
 
 	/* See asm-sparc/uaccess.h */
@@ -296,52 +295,14 @@
 	unsigned long old_len, unsigned long new_len,
 	unsigned long flags, unsigned long new_addr)
 {
-	struct vm_area_struct *vma;
 	unsigned long ret = -EINVAL;
-	if (ARCH_SUN4C_SUN4) {
-		if (old_len > 0x20000000 || new_len > 0x20000000)
-			goto out;
-		if (addr < 0xe0000000 && addr + old_len > 0x20000000)
-			goto out;
-	}
-	if (old_len > TASK_SIZE - PAGE_SIZE ||
-	    new_len > TASK_SIZE - PAGE_SIZE)
+
+	if (unlikely(sparc_mmap_check(addr, old_len)))
+		goto out;
+	if (unlikely(sparc_mmap_check(new_addr, new_len)))
 		goto out;
 	down_write(&current->mm->mmap_sem);
-	if (flags & MREMAP_FIXED) {
-		if (ARCH_SUN4C_SUN4 &&
-		    new_addr < 0xe0000000 &&
-		    new_addr + new_len > 0x20000000)
-			goto out_sem;
-		if (new_addr + new_len > TASK_SIZE - PAGE_SIZE)
-			goto out_sem;
-	} else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 &&
-		    addr + new_len > 0x20000000) ||
-		   addr + new_len > TASK_SIZE - PAGE_SIZE) {
-		unsigned long map_flags = 0;
-		struct file *file = NULL;
-
-		ret = -ENOMEM;
-		if (!(flags & MREMAP_MAYMOVE))
-			goto out_sem;
-
-		vma = find_vma(current->mm, addr);
-		if (vma) {
-			if (vma->vm_flags & VM_SHARED)
-				map_flags |= MAP_SHARED;
-			file = vma->vm_file;
-		}
-
-		new_addr = get_unmapped_area(file, addr, new_len,
-				     vma ? vma->vm_pgoff : 0,
-				     map_flags);
-		ret = new_addr;
-		if (new_addr & ~PAGE_MASK)
-			goto out_sem;
-		flags |= MREMAP_FIXED;
-	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-out_sem:
 	up_write(&current->mm->mmap_sem);
 out:
 	return ret;       
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index b49d3b6..f25e1da 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -27,11 +27,12 @@
 
 		.text		
 		.align	64
-		.globl	etrap, etrap_irq, etraptl1
+		.globl	etrap_syscall, etrap, etrap_irq, etraptl1
 etrap:		rdpr	%pil, %g2
-etrap_irq:
-		TRAP_LOAD_THREAD_REG(%g6, %g1)
+etrap_irq:	clr	%g3
+etrap_syscall:	TRAP_LOAD_THREAD_REG(%g6, %g1)
 		rdpr	%tstate, %g1
+		or	%g1, %g3, %g1
 		sllx	%g2, 20, %g3
 		andcc	%g1, TSTATE_PRIV, %g0
 		or	%g1, %g3, %g1
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 500ac6d..4129c04 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -503,6 +503,8 @@
 			      unsigned long stack_size)
 {
 	int __user *parent_tid_ptr, *child_tid_ptr;
+	unsigned long orig_i1 = regs->u_regs[UREG_I1];
+	long ret;
 
 #ifdef CONFIG_COMPAT
 	if (test_thread_flag(TIF_32BIT)) {
@@ -515,9 +517,19 @@
 		child_tid_ptr = (int __user *) regs->u_regs[UREG_I4];
 	}
 
-	return do_fork(clone_flags, stack_start,
-		       regs, stack_size,
-		       parent_tid_ptr, child_tid_ptr);
+	ret = do_fork(clone_flags, stack_start,
+		      regs, stack_size,
+		      parent_tid_ptr, child_tid_ptr);
+
+	/* If we get an error and potentially restart the system
+	 * call, we're screwed because copy_thread() clobbered
+	 * the parent's %o1.  So detect that case and restore it
+	 * here.
+	 */
+	if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+		regs->u_regs[UREG_I1] = orig_i1;
+
+	return ret;
 }
 
 /* Copy a Sparc thread.  The fork() return value conventions
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index e9fc0aa..f6c9fc9 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -287,11 +287,11 @@
 					 32 * sizeof(u64),
 					 33 * sizeof(u64));
 		if (!ret) {
-			/* Only the condition codes can be modified
-			 * in the %tstate register.
+			/* Only the condition codes and the "in syscall"
+			 * state can be modified in the %tstate register.
 			 */
-			tstate &= (TSTATE_ICC | TSTATE_XCC);
-			regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
+			tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+			regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
 			regs->tstate |= tstate;
 		}
 	}
@@ -657,8 +657,10 @@
 		switch (pos) {
 		case 32: /* PSR */
 			tstate = regs->tstate;
-			tstate &= ~(TSTATE_ICC | TSTATE_XCC);
+			tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
 			tstate |= psr_to_tstate_icc(reg);
+			if (reg & PSR_SYSCALL)
+				tstate |= TSTATE_SYSCALL;
 			regs->tstate = tstate;
 			break;
 		case 33: /* PC */
@@ -944,6 +946,8 @@
 		break;
 
 	default:
+		if (request == PTRACE_SPARC_DETACH)
+			request = PTRACE_DETACH;
 		ret = compat_ptrace_request(child, request, addr, data);
 		break;
 	}
@@ -1036,6 +1040,8 @@
 		break;
 
 	default:
+		if (request == PTRACE_SPARC_DETACH)
+			request = PTRACE_DETACH;
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index ecf6753..16689b2 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -46,7 +46,7 @@
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldx			[%g6 + TI_FLAGS], %l0
 
-1:		andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
+1:		andcc			%l0, _TIF_SIGPENDING, %g0
 		be,pt			%xcc, __handle_user_windows_continue
 		 nop
 		mov			%l5, %o1
@@ -86,7 +86,7 @@
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldx			[%g6 + TI_FLAGS], %l0
-1:		andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
+1:		andcc			%l0, _TIF_SIGPENDING, %g0
 
 		be,pt			%xcc, __handle_perfctrs_continue
 		 sethi			%hi(TSTATE_PEF), %o0
@@ -195,7 +195,7 @@
 		 andcc			%l1, %o0, %g0
 		andcc			%l0, _TIF_NEED_RESCHED, %g0
 		bne,pn			%xcc, __handle_preemption
-		 andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
+		 andcc			%l0, _TIF_SIGPENDING, %g0
 		bne,pn			%xcc, __handle_signal
 __handle_signal_continue:
 		 ldub			[%g6 + TI_WSAVED], %o2
@@ -257,6 +257,7 @@
 		wr			%o3, %g0, %y
 		wrpr			%l4, 0x0, %pil
 		wrpr			%g0, 0x1, %tl
+		andn			%l1, TSTATE_SYSCALL, %l1
 		wrpr			%l1, %g0, %tstate
 		wrpr			%l2, %g0, %tpc
 		wrpr			%o2, %g0, %tnpc
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 45d6bf6..6e4dc67 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -247,7 +247,9 @@
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
-	set_thread_flag(TIF_RESTORE_SIGMASK);
+
+	set_restore_sigmask();
+
 	return -ERESTARTNOHAND;
 }
 
@@ -333,7 +335,7 @@
 	regs->tnpc = tnpc;
 
 	/* Prevent syscall restart.  */
-	pt_regs_clear_trap_type(regs);
+	pt_regs_clear_syscall(regs);
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sighand->siglock);
@@ -376,16 +378,29 @@
 
 static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
 {
-	unsigned long sp;
+	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
 
-	sp = regs->u_regs[UREG_FP] + STACK_BIAS;
+	/*
+	 * If we are on the alternate signal stack and would overflow it, don't.
+	 * Return an always-bogus address instead so we will die with SIGSEGV.
+	 */
+	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+		return (void __user *) -1L;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if (ka->sa.sa_flags & SA_ONSTACK) {
-		if (!on_sig_stack(sp) &&
-		    !((current->sas_ss_sp + current->sas_ss_size) & 7))
+		if (sas_ss_flags(sp) == 0)
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
+
+	/* Always align the stack frame.  This handles two cases.  First,
+	 * sigaltstack need not be mindful of platform specific stack
+	 * alignment.  Second, if we took this signal because the stack
+	 * is not aligned properly, we'd like to take the signal cleanly
+	 * and report that.
+	 */
+	sp &= ~7UL;
+
 	return (void __user *)(sp - framesize);
 }
 
@@ -486,7 +501,7 @@
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
-				     struct sigaction *sa)
+				   struct sigaction *sa)
 {
 	switch (regs->u_regs[UREG_I0]) {
 	case ERESTART_RESTARTBLOCK:
@@ -512,21 +527,19 @@
  */
 static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 {
-	struct signal_deliver_cookie cookie;
 	struct k_sigaction ka;
+	int restart_syscall;
 	sigset_t *oldset;
 	siginfo_t info;
 	int signr;
 	
 	if (pt_regs_is_syscall(regs) &&
 	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
-		pt_regs_clear_trap_type(regs);
-		cookie.restart_syscall = 1;
+		restart_syscall = 1;
 	} else
-		cookie.restart_syscall = 0;
-	cookie.orig_i0 = orig_i0;
+		restart_syscall = 0;
 
-	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
 		oldset = &current->saved_sigmask;
 	else
 		oldset = &current->blocked;
@@ -534,77 +547,62 @@
 #ifdef CONFIG_COMPAT
 	if (test_thread_flag(TIF_32BIT)) {
 		extern void do_signal32(sigset_t *, struct pt_regs *,
-					struct signal_deliver_cookie *);
-		do_signal32(oldset, regs, &cookie);
+					int restart_syscall,
+					unsigned long orig_i0);
+		do_signal32(oldset, regs, restart_syscall, orig_i0);
 		return;
 	}
 #endif	
 
-	signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	/* If the debugger messes with the program counter, it clears
+	 * the software "in syscall" bit, directing us to not perform
+	 * a syscall restart.
+	 */
+	if (restart_syscall && !pt_regs_is_syscall(regs))
+		restart_syscall = 0;
+
 	if (signr > 0) {
-		if (cookie.restart_syscall)
-			syscall_restart(cookie.orig_i0, regs, &ka.sa);
+		if (restart_syscall)
+			syscall_restart(orig_i0, regs, &ka.sa);
 		handle_signal(signr, &ka, &info, oldset, regs);
 
-		/* a signal was successfully delivered; the saved
+		/* A signal was successfully delivered; the saved
 		 * sigmask will have been stored in the signal frame,
 		 * and will be restored by sigreturn, so we can simply
-		 * clear the TIF_RESTORE_SIGMASK flag.
+		 * clear the TS_RESTORE_SIGMASK flag.
 		 */
-		if (test_thread_flag(TIF_RESTORE_SIGMASK))
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		return;
 	}
-	if (cookie.restart_syscall &&
+	if (restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = cookie.orig_i0;
+		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
-	if (cookie.restart_syscall &&
+	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
 
-	/* if there's no signal to deliver, we just put the saved sigmask
+	/* If there's no signal to deliver, we just put the saved sigmask
 	 * back
 	 */
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 }
 
 void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
 {
-	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(regs, orig_i0);
 }
-
-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
-{
-	struct signal_deliver_cookie *cp = cookie;
-
-	if (cp->restart_syscall &&
-	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = cp->orig_i0;
-		regs->tpc -= 4;
-		regs->tnpc -= 4;
-		cp->restart_syscall = 0;
-	}
-	if (cp->restart_syscall &&
-	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-		regs->u_regs[UREG_G1] = __NR_restart_syscall;
-		regs->tpc -= 4;
-		regs->tnpc -= 4;
-		cp->restart_syscall = 0;
-	}
-}
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 9415d2c..97cdd1b 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -269,7 +269,7 @@
 	regs->tstate |= psr_to_tstate_icc(psr);
 
 	/* Prevent syscall restart.  */
-	pt_regs_clear_trap_type(regs);
+	pt_regs_clear_syscall(regs);
 
 	err |= __get_user(fpu_save, &sf->fpu_save);
 	if (fpu_save)
@@ -355,7 +355,7 @@
 	regs->tstate |= psr_to_tstate_icc(psr);
 
 	/* Prevent syscall restart.  */
-	pt_regs_clear_trap_type(regs);
+	pt_regs_clear_syscall(regs);
 
 	err |= __get_user(fpu_save, &sf->fpu_save);
 	if (fpu_save)
@@ -406,11 +406,27 @@
 	regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
 	sp = regs->u_regs[UREG_FP];
 	
+	/*
+	 * If we are on the alternate signal stack and would overflow it, don't.
+	 * Return an always-bogus address instead so we will die with SIGSEGV.
+	 */
+	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+		return (void __user *) -1L;
+
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if (sa->sa_flags & SA_ONSTACK) {
-		if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
+		if (sas_ss_flags(sp) == 0)
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
+
+	/* Always align the stack frame.  This handles two cases.  First,
+	 * sigaltstack need not be mindful of platform specific stack
+	 * alignment.  Second, if we took this signal because the stack
+	 * is not aligned properly, we'd like to take the signal cleanly
+	 * and report that.
+	 */
+	sp &= ~7UL;
+
 	return (void __user *)(sp - framesize);
 }
 
@@ -752,48 +768,55 @@
  * mistake.
  */
 void do_signal32(sigset_t *oldset, struct pt_regs * regs,
-		 struct signal_deliver_cookie *cookie)
+		 int restart_syscall, unsigned long orig_i0)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
 	int signr;
 	
-	signr = get_signal_to_deliver(&info, &ka, regs, cookie);
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	/* If the debugger messes with the program counter, it clears
+	 * the "in syscall" bit, directing us to not perform a syscall
+	 * restart.
+	 */
+	if (restart_syscall && !pt_regs_is_syscall(regs))
+		restart_syscall = 0;
+
 	if (signr > 0) {
-		if (cookie->restart_syscall)
-			syscall_restart32(cookie->orig_i0, regs, &ka.sa);
+		if (restart_syscall)
+			syscall_restart32(orig_i0, regs, &ka.sa);
 		handle_signal32(signr, &ka, &info, oldset, regs);
 
-		/* a signal was successfully delivered; the saved
+		/* A signal was successfully delivered; the saved
 		 * sigmask will have been stored in the signal frame,
 		 * and will be restored by sigreturn, so we can simply
-		 * clear the TIF_RESTORE_SIGMASK flag.
+		 * clear the TS_RESTORE_SIGMASK flag.
 		 */
-		if (test_thread_flag(TIF_RESTORE_SIGMASK))
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		return;
 	}
-	if (cookie->restart_syscall &&
+	if (restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = cookie->orig_i0;
+		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
-	if (cookie->restart_syscall &&
+	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
 
-	/* if there's no signal to deliver, we just put the saved sigmask
+	/* If there's no signal to deliver, we just put the saved sigmask
 	 * back
 	 */
-	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
+	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 }
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 3aba476..0d6403a 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -865,21 +865,14 @@
 	void *info = call_data->info;
 
 	clear_softint(1 << irq);
-
-	irq_enter();
-
-	if (!call_data->wait) {
-		/* let initiator proceed after getting data */
-		atomic_inc(&call_data->finished);
-	}
-
-	func(info);
-
-	irq_exit();
-
 	if (call_data->wait) {
 		/* let initiator proceed only after completion */
+		func(info);
 		atomic_inc(&call_data->finished);
+	} else {
+		/* let initiator proceed after getting data */
+		atomic_inc(&call_data->finished);
+		func(info);
 	}
 }
 
@@ -1041,9 +1034,7 @@
 
 void smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
-	irq_enter();
 	clear_softint(1 << irq);
-	irq_exit();
 }
 
 void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
@@ -1051,8 +1042,6 @@
 	struct mm_struct *mm;
 	unsigned long flags;
 
-	irq_enter();
-
 	clear_softint(1 << irq);
 
 	/* See if we need to allocate a new TLB context because
@@ -1072,8 +1061,6 @@
 	load_secondary_context(mm);
 	__flush_tlb_mm(CTX_HWBITS(mm->context),
 		       SECONDARY_CONTEXT);
-
-	irq_exit();
 }
 
 void smp_new_mmu_context_version(void)
@@ -1239,8 +1226,6 @@
 {
 	clear_softint(1 << irq);
 
-	irq_enter();
-
 	preempt_disable();
 
 	__asm__ __volatile__("flushw");
@@ -1253,8 +1238,6 @@
 	prom_world(0);
 
 	preempt_enable();
-
-	irq_exit();
 }
 
 /* /proc/profile writes can call this, don't __init it please. */
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 8d4761f..ac1bff5 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -542,20 +542,19 @@
 	return ret;
 }
 
-int sparc64_mmap_check(unsigned long addr, unsigned long len,
-		unsigned long flags)
+int sparc64_mmap_check(unsigned long addr, unsigned long len)
 {
 	if (test_thread_flag(TIF_32BIT)) {
 		if (len >= STACK_TOP32)
 			return -EINVAL;
 
-		if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
+		if (addr > STACK_TOP32 - len)
 			return -EINVAL;
 	} else {
 		if (len >= VA_EXCLUDE_START)
 			return -EINVAL;
 
-		if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
+		if (invalid_64bit_range(addr, len))
 			return -EINVAL;
 	}
 
@@ -609,46 +608,19 @@
 	unsigned long old_len, unsigned long new_len,
 	unsigned long flags, unsigned long new_addr)
 {
-	struct vm_area_struct *vma;
 	unsigned long ret = -EINVAL;
 
 	if (test_thread_flag(TIF_32BIT))
 		goto out;
 	if (unlikely(new_len >= VA_EXCLUDE_START))
 		goto out;
-	if (unlikely(invalid_64bit_range(addr, old_len)))
+	if (unlikely(sparc64_mmap_check(addr, old_len)))
+		goto out;
+	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
 		goto out;
 
 	down_write(&current->mm->mmap_sem);
-	if (flags & MREMAP_FIXED) {
-		if (invalid_64bit_range(new_addr, new_len))
-			goto out_sem;
-	} else if (invalid_64bit_range(addr, new_len)) {
-		unsigned long map_flags = 0;
-		struct file *file = NULL;
-
-		ret = -ENOMEM;
-		if (!(flags & MREMAP_MAYMOVE))
-			goto out_sem;
-
-		vma = find_vma(current->mm, addr);
-		if (vma) {
-			if (vma->vm_flags & VM_SHARED)
-				map_flags |= MAP_SHARED;
-			file = vma->vm_file;
-		}
-
-		/* MREMAP_FIXED checked above. */
-		new_addr = get_unmapped_area(file, addr, new_len,
-				    vma ? vma->vm_pgoff : 0,
-				    map_flags);
-		ret = new_addr;
-		if (new_addr & ~PAGE_MASK)
-			goto out_sem;
-		flags |= MREMAP_FIXED;
-	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-out_sem:
 	up_write(&current->mm->mmap_sem);
 out:
 	return ret;       
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 161ce47..ba5bd62 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -236,13 +236,6 @@
 
 /* 32-bit timeval and related flotsam.  */
 
-static long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
-	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
-		(__get_user(o->tv_sec, &i->tv_sec) |
-		 __get_user(o->tv_usec, &i->tv_usec)));
-}
-
 static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
 {
 	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
@@ -757,30 +750,6 @@
 	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
 }
 
-asmlinkage long sys32_utimes(char __user *filename,
-			     struct compat_timeval __user *tvs)
-{
-	struct timespec tv[2];
-
-	if (tvs) {
-		struct timeval ktvs[2];
-		if (get_tv32(&ktvs[0], tvs) ||
-		    get_tv32(&ktvs[1], 1+tvs))
-			return -EFAULT;
-
-		if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 ||
-		    ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000)
-			return -EINVAL;
-
-		tv[0].tv_sec = ktvs[0].tv_sec;
-		tv[0].tv_nsec = 1000 * ktvs[0].tv_usec;
-		tv[1].tv_sec = ktvs[1].tv_sec;
-		tv[1].tv_nsec = 1000 * ktvs[1].tv_usec;
-	}
-
-	return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0);
-}
-
 /* These are here just in case some old sparc32 binary calls it. */
 asmlinkage long sys32_pause(void)
 {
@@ -898,44 +867,15 @@
 	unsigned long old_len, unsigned long new_len,
 	unsigned long flags, u32 __new_addr)
 {
-	struct vm_area_struct *vma;
 	unsigned long ret = -EINVAL;
 	unsigned long new_addr = __new_addr;
 
-	if (old_len > STACK_TOP32 || new_len > STACK_TOP32)
+	if (unlikely(sparc64_mmap_check(addr, old_len)))
 		goto out;
-	if (addr > STACK_TOP32 - old_len)
+	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
 		goto out;
 	down_write(&current->mm->mmap_sem);
-	if (flags & MREMAP_FIXED) {
-		if (new_addr > STACK_TOP32 - new_len)
-			goto out_sem;
-	} else if (addr > STACK_TOP32 - new_len) {
-		unsigned long map_flags = 0;
-		struct file *file = NULL;
-
-		ret = -ENOMEM;
-		if (!(flags & MREMAP_MAYMOVE))
-			goto out_sem;
-
-		vma = find_vma(current->mm, addr);
-		if (vma) {
-			if (vma->vm_flags & VM_SHARED)
-				map_flags |= MAP_SHARED;
-			file = vma->vm_file;
-		}
-
-		/* MREMAP_FIXED checked above. */
-		new_addr = get_unmapped_area(file, addr, new_len,
-				    vma ? vma->vm_pgoff : 0,
-				    map_flags);
-		ret = new_addr;
-		if (new_addr & ~PAGE_MASK)
-			goto out_sem;
-		flags |= MREMAP_FIXED;
-	}
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
-out_sem:
 	up_write(&current->mm->mmap_sem);
 out:
 	return ret;       
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index a4fef2b..8b5282d 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -45,7 +45,7 @@
 /*120*/	.word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
 	.word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate
 /*130*/	.word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
-	.word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64
+	.word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
 /*140*/	.word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
 	.word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write
 /*150*/	.word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 4cad0b3..a9828d7 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -610,8 +610,6 @@
 
 static void __init inherit_prom_mappings(void)
 {
-	read_obp_translations();
-
 	/* Now fixup OBP's idea about where we really are mapped. */
 	printk("Remapping the kernel... ");
 	remap_kernel();
@@ -771,6 +769,9 @@
 		initrd_end = ramdisk_image + sparc_ramdisk_size;
 
 		lmb_reserve(initrd_start, initrd_end);
+
+		initrd_start += PAGE_OFFSET;
+		initrd_end += PAGE_OFFSET;
 	}
 #endif
 }
@@ -1744,7 +1745,17 @@
 
 	lmb_init();
 
-	/* Find available physical memory... */
+	/* Find available physical memory...
+	 *
+	 * Read it twice in order to work around a bug in openfirmware.
+	 * The call to grab this table itself can cause openfirmware to
+	 * allocate memory, which in turn can take away some space from
+	 * the list of available memory.  Reading it twice makes sure
+	 * we really do get the final value.
+	 */
+	read_obp_translations();
+	read_obp_memory("reg", &pall[0], &pall_ents);
+	read_obp_memory("available", &pavail[0], &pavail_ents);
 	read_obp_memory("available", &pavail[0], &pavail_ents);
 
 	phys_base = 0xffffffffffffffffUL;
@@ -1785,8 +1796,6 @@
 	
 	inherit_prom_mappings();
 	
-	read_obp_memory("reg", &pall[0], &pall_ents);
-
 	init_kpte_bitmap();
 
 	/* Ok, we can use our TLB miss and window trap handlers safely.  */
@@ -2362,16 +2371,3 @@
 	__asm__ __volatile__("wrpr	%0, 0, %%pstate"
 			     : : "r" (pstate));
 }
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-
-void online_page(struct page *page)
-{
-	ClearPageReserved(page);
-	init_page_count(page);
-	__free_page(page);
-	totalram_pages++;
-	num_physpages++;
-}
-
-#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index 3a4b396..1b238eb 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -145,14 +145,14 @@
 	  systems, it is safe to say N.
 
 config RAW_DRIVER
-        tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
+        tristate "RAW driver (/dev/raw/rawN)"
+	depends on BLOCK
         help
           The raw driver permits block devices to be bound to /dev/raw/rawN.
           Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
           See the raw(8) manpage for more details.
 
-          The raw driver is deprecated and will be removed soon.
-          Applications should simply open the device (eg /dev/hda1)
+          Applications should preferably open the device (eg /dev/hda1)
           with the O_DIRECT flag.
 
 config MAX_RAW_DEVS
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 01b97c1..dbeab15 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -77,10 +77,7 @@
 KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
 			 -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
 KBUILD_CFLAGS += $(KERNEL_DEFINES)
-# 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:
-KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
-			echo $(call cc-option,-fno-unit-at-a-time); fi ;)
+KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
 PHONY += linux
 
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 0257640..cfeb3f4 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -11,6 +11,7 @@
 #include <termios.h>
 #include <sys/ioctl.h>
 #include "chan_user.h"
+#include "kern_constants.h"
 #include "os.h"
 #include "um_malloc.h"
 #include "user.h"
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index ca8c9e1..f5701fd 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -8,7 +8,7 @@
 
 static inline void *cow_malloc(int size)
 {
-	return kmalloc(size, UM_GFP_KERNEL);
+	return uml_kmalloc(size, UM_GFP_KERNEL);
 }
 
 static inline void cow_free(void *ptr)
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index f23c109..f8e85e0 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -34,7 +34,7 @@
 {
 	struct sockaddr_un *sun;
 
-	sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
 	if (sun == NULL) {
 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
 		       "failed\n");
@@ -83,7 +83,7 @@
 		goto out_close;
 	}
 
-	sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
 	if (sun == NULL) {
 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
 		       "failed\n");
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 0a2bb5b..f5a981a 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -40,7 +40,7 @@
 		return NULL;
 	}
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index ff1b22b..368219c 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -154,7 +154,7 @@
 	case SNDCTL_DSP_SUBDIVIDE:
 	case SNDCTL_DSP_SETFRAGMENT:
 		if (get_user(data, (int __user *) arg))
-			return EFAULT;
+			return -EFAULT;
 		break;
 	default:
 		break;
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 10b86e1..5047490 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -191,9 +191,9 @@
 	line_flush_buffer(tty);
 }
 
-void line_put_char(struct tty_struct *tty, unsigned char ch)
+int line_put_char(struct tty_struct *tty, unsigned char ch)
 {
-	line_write(tty, &ch, sizeof(ch));
+	return line_write(tty, &ch, sizeof(ch));
 }
 
 int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 5f647d7..ee19e91 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <netinet/in.h>
+#include "kern_constants.h"
 #include "mcast.h"
 #include "net_user.h"
 #include "um_malloc.h"
@@ -24,7 +25,7 @@
 {
 	struct sockaddr_in *sin;
 
-	sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
+	sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
 	if (sin == NULL) {
 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
 		       "failed\n");
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index abf2653..9415dd9 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -222,7 +222,7 @@
 		netmask[2], netmask[3]);
 
 	output_len = UM_KERN_PAGE_SIZE;
-	output = kmalloc(output_len, UM_GFP_KERNEL);
+	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
 	if (output == NULL)
 		printk(UM_KERN_ERR "change : failed to allocate output "
 		       "buffer\n");
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index d269ca3..b49bf56 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -47,7 +47,7 @@
 	if (kern_data == NULL)
 		return NULL;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		goto err;
 
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 49c79dd..1113911 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -29,7 +29,7 @@
 {
 	struct pty_chan *data;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 71f0959..4949044 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
+/* Copyright (C) 2005 - 2008 Jeff Dike <jdike@{linux.intel,addtoit}.com> */
+
 /* Much of this ripped from drivers/char/hw_random.c, see there for other
  * copyright.
  *
@@ -8,16 +9,18 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/interrupt.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
+#include "irq_kern.h"
 #include "os.h"
 
 /*
  * core module and version information
  */
 #define RNG_VERSION "1.0.0"
-#define RNG_MODULE_NAME "random"
+#define RNG_MODULE_NAME "hw_random"
 
 #define RNG_MISCDEV_MINOR		183 /* official */
 
@@ -26,47 +29,67 @@
  * protects against a module being loaded twice at the same time.
  */
 static int random_fd = -1;
+static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
 
 static int rng_dev_open (struct inode *inode, struct file *filp)
 {
 	/* enforce read-only access to this chrdev */
 	if ((filp->f_mode & FMODE_READ) == 0)
 		return -EINVAL;
-	if (filp->f_mode & FMODE_WRITE)
+	if ((filp->f_mode & FMODE_WRITE) != 0)
 		return -EINVAL;
 
 	return 0;
 }
 
+static atomic_t host_sleep_count = ATOMIC_INIT(0);
+
 static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
-                             loff_t * offp)
+			     loff_t *offp)
 {
-        u32 data;
-        int n, ret = 0, have_data;
+	u32 data;
+	int n, ret = 0, have_data;
 
-        while(size){
-                n = os_read_file(random_fd, &data, sizeof(data));
-                if(n > 0){
-                        have_data = n;
-                        while (have_data && size) {
-                                if (put_user((u8)data, buf++)) {
-                                        ret = ret ? : -EFAULT;
-                                        break;
-                                }
-                                size--;
-                                ret++;
-                                have_data--;
-                                data>>=8;
-                        }
-                }
-                else if(n == -EAGAIN){
-                        if (filp->f_flags & O_NONBLOCK)
-                                return ret ? : -EAGAIN;
+	while (size) {
+		n = os_read_file(random_fd, &data, sizeof(data));
+		if (n > 0) {
+			have_data = n;
+			while (have_data && size) {
+				if (put_user((u8) data, buf++)) {
+					ret = ret ? : -EFAULT;
+					break;
+				}
+				size--;
+				ret++;
+				have_data--;
+				data >>= 8;
+			}
+		}
+		else if (n == -EAGAIN) {
+			DECLARE_WAITQUEUE(wait, current);
 
-                        if(need_resched())
-                                schedule_timeout_interruptible(1);
-                }
-                else return n;
+			if (filp->f_flags & O_NONBLOCK)
+				return ret ? : -EAGAIN;
+
+			atomic_inc(&host_sleep_count);
+			reactivate_fd(random_fd, RANDOM_IRQ);
+			add_sigio_fd(random_fd);
+
+			add_wait_queue(&host_read_wait, &wait);
+			set_task_state(current, TASK_INTERRUPTIBLE);
+
+			schedule();
+			set_task_state(current, TASK_RUNNING);
+			remove_wait_queue(&host_read_wait, &wait);
+
+			if (atomic_dec_and_test(&host_sleep_count)) {
+				ignore_sigio_fd(random_fd);
+				deactivate_fd(random_fd, RANDOM_IRQ);
+			}
+		}
+		else
+			return n;
+
 		if (signal_pending (current))
 			return ret ? : -ERESTARTSYS;
 	}
@@ -86,6 +109,13 @@
 	&rng_chrdev_ops,
 };
 
+static irqreturn_t random_interrupt(int irq, void *data)
+{
+	wake_up(&host_read_wait);
+
+	return IRQ_HANDLED;
+}
+
 /*
  * rng_init - initialize RNG module
  */
@@ -93,28 +123,33 @@
 {
 	int err;
 
-        err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
-        if(err < 0)
-                goto out;
+	err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
+	if (err < 0)
+		goto out;
 
-        random_fd = err;
+	random_fd = err;
 
-        err = os_set_fd_block(random_fd, 0);
-        if(err)
+	err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
+			     IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random",
+			     NULL);
+	if (err)
 		goto err_out_cleanup_hw;
 
+	sigio_broken(random_fd, 1);
+
 	err = misc_register (&rng_miscdev);
 	if (err) {
-		printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
+		printk (KERN_ERR RNG_MODULE_NAME ": misc device register "
+			"failed\n");
 		goto err_out_cleanup_hw;
 	}
+out:
+	return err;
 
- out:
-        return err;
-
- err_out_cleanup_hw:
-        random_fd = -1;
-        goto out;
+err_out_cleanup_hw:
+	os_close_file(random_fd);
+	random_fd = -1;
+	goto out;
 }
 
 /*
@@ -122,6 +157,7 @@
  */
 static void __exit rng_cleanup (void)
 {
+	os_close_file(random_fd);
 	misc_deregister (&rng_miscdev);
 }
 
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 8b80505..a1c2d2c 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -96,7 +96,7 @@
 	pid = err;
 
 	output_len = UM_KERN_PAGE_SIZE;
-	output = kmalloc(output_len, UM_GFP_KERNEL);
+	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
 	if (output == NULL) {
 		printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
 		       "buffer\n");
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index c930fed..495858a 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -29,7 +29,7 @@
 	}
 	str++;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 	*data = ((struct tty_chan) { .dev 	= str,
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 5e45e39..44ad160 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1178,8 +1178,8 @@
 	 * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
 	 * for the original diagnosis.
 	 */
-	if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
-			   sizeof(unsigned long) - 1))
+	if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
+					 sizeof(unsigned long)) - 1))
 		(*cow_offset)--;
 
 	bitmap_words[0] = bitmap[*cow_offset];
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 8a1c18a..da2caa5 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -30,7 +30,7 @@
 {
 	struct xterm_chan *data;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 	*data = ((struct xterm_chan) { .pid 		= -1,
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
index cac542d..58e852d 100644
--- a/arch/um/include/as-layout.h
+++ b/arch/um/include/as-layout.h
@@ -23,16 +23,16 @@
  */
 
 #ifdef __ASSEMBLY__
-#define _AC(X, Y)	(Y)
+#define _UML_AC(X, Y)	(Y)
 #else
-#define __AC(X, Y)	(X (Y))
-#define _AC(X, Y)	__AC(X, Y)
+#define __UML_AC(X, Y)	(X(Y))
+#define _UML_AC(X, Y)	__UML_AC(X, Y)
 #endif
 
-#define STUB_START _AC(, 0x100000)
-#define STUB_CODE _AC((unsigned long), STUB_START)
-#define STUB_DATA _AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
-#define STUB_END _AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
+#define STUB_START _UML_AC(, 0x100000)
+#define STUB_CODE _UML_AC((unsigned long), STUB_START)
+#define STUB_DATA _UML_AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
+#define STUB_END _UML_AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 1223f2c..311a0d3 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -58,11 +58,11 @@
 };
 
 #define LINE_INIT(str, d) \
-	{ .count_lock =	SPIN_LOCK_UNLOCKED, \
+	{ .count_lock =	__SPIN_LOCK_UNLOCKED((str).count_lock), \
 	  .init_str =	str,	\
 	  .init_pri =	INIT_STATIC, \
 	  .valid =	1, \
-	  .lock =	SPIN_LOCK_UNLOCKED, \
+	  .lock =	__SPIN_LOCK_UNLOCKED((str).lock), \
 	  .driver =	d }
 
 extern void line_close(struct tty_struct *tty, struct file * filp);
@@ -71,7 +71,7 @@
 		      char *init, char **error_out);
 extern int line_write(struct tty_struct *tty, const unsigned char *buf,
 		      int len);
-extern void line_put_char(struct tty_struct *tty, unsigned char ch);
+extern int line_put_char(struct tty_struct *tty, unsigned char ch);
 extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
 extern int line_chars_in_buffer(struct tty_struct *tty);
 extern void line_flush_buffer(struct tty_struct *tty);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 32c799e..e2716ac 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -290,6 +290,7 @@
 extern int add_sigio_fd(int fd);
 extern int ignore_sigio_fd(int fd);
 extern void maybe_sigio_broken(int fd, int read);
+extern void sigio_broken(int fd, int read);
 
 /* sys-x86_64/prctl.c */
 extern int os_arch_prctl(int pid, int code, unsigned long *addr);
diff --git a/arch/um/include/process.h b/arch/um/include/process.h
index 5af9157..bb873a5 100644
--- a/arch/um/include/process.h
+++ b/arch/um/include/process.h
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
@@ -8,18 +8,10 @@
 
 #include <signal.h>
 
-extern void sig_handler(int sig, struct sigcontext sc);
-extern void alarm_handler(int sig, struct sigcontext sc);
+/* Copied from linux/compiler-gcc.h since we can't include it directly */
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+extern void sig_handler(int sig, struct sigcontext *sc);
+extern void alarm_handler(int sig, struct sigcontext *sc);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
index cd2327d..3d31bba 100644
--- a/arch/um/include/skas_ptrace.h
+++ b/arch/um/include/skas_ptrace.h
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
@@ -12,14 +12,3 @@
 #include "sysdep/skas_ptrace.h"
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h
index 7565072..ef56247 100644
--- a/arch/um/include/sysdep-i386/ptrace_user.h
+++ b/arch/um/include/sysdep-i386/ptrace_user.h
@@ -41,38 +41,10 @@
 #define PT_SP_OFFSET PT_OFFSET(UESP)
 #define PT_SP(regs) ((regs)[UESP])
 
-#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE)
+#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE)
 
 #ifndef FRAME_SIZE
 #define FRAME_SIZE (17)
 #endif
-#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
-
-#define FP_FRAME_SIZE (27)
-#define FPX_FRAME_SIZE (128)
-
-#ifdef PTRACE_GETREGS
-#define UM_HAVE_GETREGS
-#endif
-
-#ifdef PTRACE_SETREGS
-#define UM_HAVE_SETREGS
-#endif
-
-#ifdef PTRACE_GETFPREGS
-#define UM_HAVE_GETFPREGS
-#endif
-
-#ifdef PTRACE_SETFPREGS
-#define UM_HAVE_SETFPREGS
-#endif
-
-#ifdef PTRACE_GETFPXREGS
-#define UM_HAVE_GETFPXREGS
-#endif
-
-#ifdef PTRACE_SETFPXREGS
-#define UM_HAVE_SETFPXREGS
-#endif
 
 #endif
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index 67e7712..f583c87 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -10,7 +10,7 @@
 
 #define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
 
-#define GET_FAULTINFO_FROM_SC(fi,sc) \
+#define GET_FAULTINFO_FROM_SC(fi, sc) \
 	{ \
 		(fi).cr2 = SC_CR2(sc); \
 		(fi).error_code = SC_ERR(sc); \
diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
index 45c0bd8..4dbccdb 100644
--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -48,7 +48,8 @@
 #define PT_ORIG_RAX_OFFSET (ORIG_RAX)
 #define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)])
 
-/* x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
+/*
+ * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
  * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the
  * 2.4 name and value for 2.4 host compatibility.
  */
@@ -56,7 +57,8 @@
 #define PTRACE_OLDSETOPTIONS 21
 #endif
 
-/* These are before the system call, so the system call number is RAX
+/*
+ * These are before the system call, so the system call number is RAX
  * rather than ORIG_RAX, and arg4 is R10 rather than RCX
  */
 #define REGS_SYSCALL_NR PT_INDEX(RAX)
@@ -73,14 +75,3 @@
 #define FP_SIZE (HOST_FP_SIZE)
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h
index 0ad17cb..c554d70 100644
--- a/arch/um/include/um_malloc.h
+++ b/arch/um/include/um_malloc.h
@@ -8,15 +8,12 @@
 
 #include "kern_constants.h"
 
-extern void *__kmalloc(int size, int flags);
-static inline void *kmalloc(int size, int flags)
-{
-	return __kmalloc(size, flags);
-}
-
+extern void *uml_kmalloc(int size, int flags);
 extern void kfree(const void *ptr);
 
 extern void *vmalloc(unsigned long size);
 extern void vfree(void *ptr);
 
 #endif /* __UM_MALLOC_H__ */
+
+
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 26090b7..9975e1a 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -1,4 +1,5 @@
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
 
 OUTPUT_FORMAT(ELF_FORMAT)
 OUTPUT_ARCH(ELF_ARCH)
@@ -21,7 +22,7 @@
 	_einittext = .;
   }
 
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
 
   /* Read-only sections, merged into text segment: */
   .hash           : { *(.hash) }
@@ -68,9 +69,9 @@
     /* .gnu.warning sections are handled specially by elf32.em.  */
     *(.gnu.warning)
 
-    . = ALIGN(4096);
+    . = ALIGN(PAGE_SIZE);
   } =0x90909090
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
   .syscall_stub : {
 	__syscall_stub_start = .;
 	*(.__syscall_stub*)
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 2eea1ff..b0ee646 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -375,3 +375,8 @@
 	return pmd;
 }
 #endif
+
+void *uml_kmalloc(int size, int flags)
+{
+	return kmalloc(size, flags);
+}
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 0d0cea2..c3e2f36 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -75,7 +75,7 @@
 
 static cycle_t itimer_read(void)
 {
-	return os_nsecs();
+	return os_nsecs() / 1000;
 }
 
 static struct clocksource itimer_clocksource = {
@@ -83,7 +83,7 @@
 	.rating		= 300,
 	.read		= itimer_read,
 	.mask		= CLOCKSOURCE_MASK(64),
-	.mult		= 1,
+	.mult		= 1000,
 	.shift		= 0,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 56deed6..9db85b2 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -150,7 +150,7 @@
 static int __init no_skas_debug_setup(char *line, int *add)
 {
 	printf("'debug' is not necessary to gdb UML in skas mode - run \n");
-	printf("'gdb linux'");
+	printf("'gdb linux'\n");
 
 	return 0;
 }
@@ -258,6 +258,7 @@
 {
 	unsigned long avail, diff;
 	unsigned long virtmem_size, max_physmem;
+	unsigned long stack;
 	unsigned int i;
 	int add;
 	char * mode;
@@ -348,7 +349,9 @@
 	}
 
 	virtmem_size = physmem_size;
-	avail = TASK_SIZE - start_vm;
+	stack = (unsigned long) argv;
+	stack &= ~(1024 * 1024 - 1);
+	avail = stack - start_vm;
 	if (physmem_size > avail)
 		virtmem_size = avail;
 	end_vm = start_vm + virtmem_size;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 5828c1d..11b8352 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -1,4 +1,5 @@
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
 
 OUTPUT_FORMAT(ELF_FORMAT)
 OUTPUT_ARCH(ELF_ARCH)
@@ -26,7 +27,7 @@
 	INIT_TEXT
 	_einittext = .;
   }
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
 
   .text      :
   {
@@ -39,7 +40,7 @@
     *(.gnu.linkonce.t*)
   }
 
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
   .syscall_stub : {
 	__syscall_stub_start = .;
 	*(.__syscall_stub*)
@@ -79,7 +80,7 @@
   .sdata     : { *(.sdata) }
   _edata  =  .;
   PROVIDE (edata = .);
-  . = ALIGN(0x1000);
+  . = ALIGN(PAGE_SIZE);
   .sbss      :
   {
    __bss_start = .;
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 6fb0b17..cc72cb2 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -52,7 +52,7 @@
 		return;
 	}
 
-	output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
+	output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
 	if (output == NULL)
 		printk(UM_KERN_ERR "etap_change : Failed to allocate output "
 		       "buffer\n");
@@ -165,7 +165,7 @@
 	err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
 			 control_fds[1], data_fds[0], data_fds[1]);
 	output_len = UM_KERN_PAGE_SIZE;
-	output = kmalloc(output_len, UM_GFP_KERNEL);
+	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
 	read_output(control_fds[0], output, output_len);
 
 	if (output == NULL)
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index f25c29a..74ca7aa 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -71,8 +71,8 @@
 	data.pre_data = pre_data;
 	data.argv = argv;
 	data.fd = fds[1];
-	data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
-					kmalloc(PATH_MAX, UM_GFP_KERNEL);
+	data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
+					uml_kmalloc(PATH_MAX, UM_GFP_KERNEL);
 	pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
 	if (pid < 0) {
 		ret = -errno;
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index abb9b0f..eee69b9 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -199,7 +199,7 @@
 		return __real_malloc(size);
 	else if (size <= UM_KERN_PAGE_SIZE)
 		/* finding contiguous pages can be hard*/
-		ret = kmalloc(size, UM_GFP_KERNEL);
+		ret = uml_kmalloc(size, UM_GFP_KERNEL);
 	else ret = vmalloc(size);
 
 	/*
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index abf47a7c..eb8f2e4 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
@@ -15,6 +15,7 @@
 #include "kern_util.h"
 #include "init.h"
 #include "os.h"
+#include "process.h"
 #include "sigio.h"
 #include "um_malloc.h"
 #include "user.h"
@@ -109,7 +110,7 @@
 	if (n <= polls->size)
 		return 0;
 
-	new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
+	new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
 	if (new == NULL) {
 		printk(UM_KERN_ERR "need_poll : failed to allocate new "
 		       "pollfds\n");
@@ -243,7 +244,7 @@
 {
 	struct pollfd *p;
 
-	p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
+	p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
 	if (p == NULL) {
 		printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
 		       "poll\n");
@@ -338,20 +339,10 @@
 	close(l_write_sigio_fds[1]);
 }
 
-/* Changed during early boot */
-static int pty_output_sigio = 0;
-static int pty_close_sigio = 0;
-
-void maybe_sigio_broken(int fd, int read)
+void sigio_broken(int fd, int read)
 {
 	int err;
 
-	if (!isatty(fd))
-		return;
-
-	if ((read || pty_output_sigio) && (!read || pty_close_sigio))
-		return;
-
 	write_sigio_workaround();
 
 	sigio_lock();
@@ -370,6 +361,21 @@
 	sigio_unlock();
 }
 
+/* Changed during early boot */
+static int pty_output_sigio;
+static int pty_close_sigio;
+
+void maybe_sigio_broken(int fd, int read)
+{
+	if (!isatty(fd))
+		return;
+
+	if ((read || pty_output_sigio) && (!read || pty_close_sigio))
+		return;
+
+	sigio_broken(fd, read);
+}
+
 static void sigio_cleanup(void)
 {
 	if (write_sigio_pid == -1)
@@ -383,7 +389,7 @@
 __uml_exitcall(sigio_cleanup);
 
 /* Used as a flag during SIGIO testing early in boot */
-static volatile int got_sigio = 0;
+static int got_sigio;
 
 static void __init handler(int sig)
 {
@@ -498,7 +504,8 @@
 	if (errno != EAGAIN)
 		printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
 		       errno);
-	while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio)
+	while (((n = read(slave, buf, sizeof(buf))) > 0) &&
+	       !({ barrier(); got_sigio; }))
 		;
 
 	if (got_sigio) {
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 3f1694b..5aade60 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -12,6 +12,7 @@
 #include "as-layout.h"
 #include "kern_util.h"
 #include "os.h"
+#include "process.h"
 #include "sysdep/barrier.h"
 #include "sysdep/sigcontext.h"
 #include "user.h"
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 1e8cba6..6be028c 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -442,7 +442,7 @@
 				unblock_signals();
 				break;
 			default:
-			        printk(UM_KERN_ERR "userspace - child stopped "
+				printk(UM_KERN_ERR "userspace - child stopped "
 				       "with signal %d\n", sig);
 				fatal_sigsegv();
 			}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 997d019..b4b36e0 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -23,6 +23,7 @@
 #include "mem_user.h"
 #include "ptrace_user.h"
 #include "registers.h"
+#include "skas.h"
 #include "skas_ptrace.h"
 
 static void ptrace_child(void)
@@ -140,14 +141,27 @@
 }
 
 /* Changed only during early boot */
-int ptrace_faultinfo = 1;
-int ptrace_ldt = 1;
-int proc_mm = 1;
-int skas_needs_stub = 0;
+int ptrace_faultinfo;
+static int disable_ptrace_faultinfo;
+
+int ptrace_ldt;
+static int disable_ptrace_ldt;
+
+int proc_mm;
+static int disable_proc_mm;
+
+int have_switch_mm;
+static int disable_switch_mm;
+
+int skas_needs_stub;
 
 static int __init skas0_cmd_param(char *str, int* add)
 {
-	ptrace_faultinfo = proc_mm = 0;
+	disable_ptrace_faultinfo = 1;
+	disable_ptrace_ldt = 1;
+	disable_proc_mm = 1;
+	disable_switch_mm = 1;
+
 	return 0;
 }
 
@@ -157,15 +171,12 @@
 	__attribute__((alias("skas0_cmd_param")));
 
 __uml_setup("skas0", skas0_cmd_param,
-		"skas0\n"
-		"    Disables SKAS3 usage, so that SKAS0 is used, unless \n"
-	        "    you specify mode=tt.\n\n");
+"skas0\n"
+"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n");
 
 __uml_setup("mode=skas0", mode_skas0_cmd_param,
-		"mode=skas0\n"
-		"    Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
-		"    specify mode=tt. Note that this was recently added - on \n"
-		"    older kernels you must use simply \"skas0\".\n\n");
+"mode=skas0\n"
+"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n");
 
 /* Changed only during early boot */
 static int force_sysemu_disabled = 0;
@@ -360,7 +371,7 @@
 
 static int __init noprocmm_cmd_param(char *str, int* add)
 {
-	proc_mm = 0;
+	disable_proc_mm = 1;
 	return 0;
 }
 
@@ -372,7 +383,7 @@
 
 static int __init noptracefaultinfo_cmd_param(char *str, int* add)
 {
-	ptrace_faultinfo = 0;
+	disable_ptrace_faultinfo = 1;
 	return 0;
 }
 
@@ -384,7 +395,7 @@
 
 static int __init noptraceldt_cmd_param(char *str, int* add)
 {
-	ptrace_ldt = 0;
+	disable_ptrace_ldt = 1;
 	return 0;
 }
 
@@ -404,17 +415,15 @@
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
 	if (n < 0) {
-		ptrace_faultinfo = 0;
 		if (errno == EIO)
 			non_fatal("not found\n");
 		else
 			perror("not found");
-	}
+	} else if (disable_ptrace_faultinfo)
+		non_fatal("found but disabled on command line\n");
 	else {
-		if (!ptrace_faultinfo)
-			non_fatal("found but disabled on command line\n");
-		else
-			non_fatal("found\n");
+		ptrace_faultinfo = 1;
+		non_fatal("found\n");
 	}
 
 	stop_ptraced_child(pid, 1, 1);
@@ -437,38 +446,30 @@
 	if (n < 0) {
 		if (errno == EIO)
 			non_fatal("not found\n");
-		else {
-			perror("not found");
-		}
-		ptrace_ldt = 0;
-	}
-	else {
-		if (ptrace_ldt)
-			non_fatal("found\n");
 		else
-			non_fatal("found, but use is disabled\n");
+			perror("not found");
+	} else if (disable_ptrace_ldt)
+		non_fatal("found, but use is disabled\n");
+	else {
+		ptrace_ldt = 1;
+		non_fatal("found\n");
 	}
 
 	stop_ptraced_child(pid, 1, 1);
-#else
-	/* PTRACE_LDT might be disabled via cmdline option.
-	 * We want to override this, else we might use the stub
-	 * without real need
-	 */
-	ptrace_ldt = 1;
 #endif
 }
 
 static inline void check_skas3_proc_mm(void)
 {
 	non_fatal("  - /proc/mm...");
-	if (access("/proc/mm", W_OK) < 0) {
-		proc_mm = 0;
+	if (access("/proc/mm", W_OK) < 0)
 		perror("not found");
-	}
-	else if (!proc_mm)
+	else if (disable_proc_mm)
 		non_fatal("found but disabled on command line\n");
-	else non_fatal("found\n");
+	else {
+		proc_mm = 1;
+		non_fatal("found\n");
+	}
 }
 
 void can_do_skas(void)
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index b613473..c6183e7 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -5,6 +5,7 @@
  */
 
 #include <errno.h>
+#include <asm/user.h>
 #include "kern_constants.h"
 #include "longjmp.h"
 #include "user.h"
@@ -74,10 +75,10 @@
 
 void arch_init_registers(int pid)
 {
-	unsigned long fpx_regs[HOST_XFP_SIZE];
+	struct user_fxsr_struct fpx_regs;
 	int err;
 
-	err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs);
+	err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
 	if (!err)
 		return;
 
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index e492805..bee98f4 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -9,7 +9,9 @@
 #include <time.h>
 #include <sys/time.h>
 #include "kern_constants.h"
+#include "kern_util.h"
 #include "os.h"
+#include "process.h"
 #include "user.h"
 
 int set_interval(void)
@@ -58,12 +60,17 @@
 long long disable_timer(void)
 {
 	struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
+	int remain, max = UM_NSEC_PER_SEC / UM_HZ;
 
 	if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
 		printk(UM_KERN_ERR "disable_timer - setitimer failed, "
 		       "errno = %d\n", errno);
 
-	return timeval_to_ns(&time.it_value);
+	remain = timeval_to_ns(&time.it_value);
+	if (remain > max)
+		remain = max;
+
+	return remain;
 }
 
 long long os_nsecs(void)
@@ -79,7 +86,44 @@
 {
 	return 0;
 }
+
+static void deliver_alarm(void)
+{
+	alarm_handler(SIGVTALRM, NULL);
+}
+
+static unsigned long long sleep_time(unsigned long long nsecs)
+{
+	return nsecs;
+}
+
 #else
+unsigned long long last_tick;
+unsigned long long skew;
+
+static void deliver_alarm(void)
+{
+	unsigned long long this_tick = os_nsecs();
+	int one_tick = UM_NSEC_PER_SEC / UM_HZ;
+
+	if (last_tick == 0)
+		last_tick = this_tick - one_tick;
+
+	skew += this_tick - last_tick;
+
+	while (skew >= one_tick) {
+		alarm_handler(SIGVTALRM, NULL);
+		skew -= one_tick;
+	}
+
+	last_tick = this_tick;
+}
+
+static unsigned long long sleep_time(unsigned long long nsecs)
+{
+	return nsecs > skew ? nsecs - skew : 0;
+}
+
 static inline long long timespec_to_us(const struct timespec *ts)
 {
 	return ((long long) ts->tv_sec * UM_USEC_PER_SEC) +
@@ -102,6 +146,8 @@
 	 */
 	if (start_usecs > usec)
 		start_usecs = usec;
+
+	start_usecs -= skew / UM_NSEC_PER_USEC;
 	tv = ((struct timeval) { .tv_sec  = start_usecs / UM_USEC_PER_SEC,
 				 .tv_usec = start_usecs % UM_USEC_PER_SEC });
 	interval = ((struct itimerval) { { 0, usec }, tv });
@@ -113,8 +159,6 @@
 }
 #endif
 
-extern void alarm_handler(int sig, struct sigcontext *sc);
-
 void idle_sleep(unsigned long long nsecs)
 {
 	struct timespec ts;
@@ -126,10 +170,12 @@
 	 */
 	if (nsecs == 0)
 		nsecs = UM_NSEC_PER_SEC / UM_HZ;
+
+	nsecs = sleep_time(nsecs);
 	ts = ((struct timespec) { .tv_sec	= nsecs / UM_NSEC_PER_SEC,
 				  .tv_nsec	= nsecs % UM_NSEC_PER_SEC });
 
 	if (nanosleep(&ts, &ts) == 0)
-		alarm_handler(SIGVTALRM, NULL);
+		deliver_alarm();
 	after_sleep_interval(&ts);
 }
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 6b44999..c9b1765 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -148,14 +148,13 @@
 int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
 	int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
-	long fpregs[HOST_FP_SIZE];
+	struct user_i387_struct fpregs;
 
-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
-	err = save_fp_registers(userspace_pid[cpu], fpregs);
+	err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
 	if (err)
 		return err;
 
-	n = copy_to_user(buf, fpregs, sizeof(fpregs));
+	n = copy_to_user(buf, &fpregs, sizeof(fpregs));
 	if(n > 0)
 		return -EFAULT;
 
@@ -165,27 +164,26 @@
 int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
 	int n, cpu = ((struct thread_info *) child->stack)->cpu;
-	long fpregs[HOST_FP_SIZE];
+	struct user_i387_struct fpregs;
 
-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
-	n = copy_from_user(fpregs, buf, sizeof(fpregs));
+	n = copy_from_user(&fpregs, buf, sizeof(fpregs));
 	if (n > 0)
 		return -EFAULT;
 
-	return restore_fp_registers(userspace_pid[cpu], fpregs);
+	return restore_fp_registers(userspace_pid[cpu],
+				    (unsigned long *) &fpregs);
 }
 
 int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 {
 	int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
-	long fpregs[HOST_XFP_SIZE];
+	struct user_fxsr_struct fpregs;
 
-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
-	err = save_fpx_registers(userspace_pid[cpu], fpregs);
+	err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
 	if (err)
 		return err;
 
-	n = copy_to_user(buf, fpregs, sizeof(fpregs));
+	n = copy_to_user(buf, &fpregs, sizeof(fpregs));
 	if(n > 0)
 		return -EFAULT;
 
@@ -195,14 +193,14 @@
 int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 {
 	int n, cpu = ((struct thread_info *) child->stack)->cpu;
-	long fpregs[HOST_XFP_SIZE];
+	struct user_fxsr_struct fpregs;
 
-	BUG_ON(sizeof(*buf) != sizeof(fpregs));
-	n = copy_from_user(fpregs, buf, sizeof(fpregs));
+	n = copy_from_user(&fpregs, buf, sizeof(fpregs));
 	if (n > 0)
 		return -EFAULT;
 
-	return restore_fpx_registers(userspace_pid[cpu], fpregs);
+	return restore_fpx_registers(userspace_pid[cpu],
+				     (unsigned long *) &fpregs);
 }
 
 long subarch_ptrace(struct task_struct *child, long request, long addr,
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 39bd32b..5f883bf 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -22,7 +22,7 @@
 	OFFSET(HOST_SC_CR2, sigcontext, cr2);
 
 	DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct));
-	DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct));
+	DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct));
 
 	DEFINE(HOST_IP, EIP);
 	DEFINE(HOST_SP, UESP);
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 2f3443c..9735854 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -24,7 +24,6 @@
 	OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
 
 	DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
-	DEFINE(HOST_XFP_SIZE, 0);
 	DEFINE_LONGS(HOST_RBX, RBX);
 	DEFINE_LONGS(HOST_RCX, RCX);
 	DEFINE_LONGS(HOST_RDI, RDI);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 845ea2b2..fe361ae 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -18,6 +18,7 @@
 ### Arch settings
 config X86
 	def_bool y
+	select HAVE_UNSTABLE_SCHED_CLOCK
 	select HAVE_IDE
 	select HAVE_OPROFILE
 	select HAVE_KPROBES
@@ -334,6 +335,7 @@
 	select GENERIC_GPIO
 	select LEDS_CLASS
 	select LEDS_GPIO
+	select NEW_LEDS
 	help
 	  This option is needed for RDC R-321x system-on-chip, also known
 	  as R-8610-(G).
@@ -1661,7 +1663,6 @@
 
 config OLPC
 	bool "One Laptop Per Child support"
-	depends on MGEODE_LX
 	default n
 	help
 	  Add support for detecting the unique features of the OLPC
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index bbdacb3..5e618c3 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -83,9 +83,7 @@
 obj-$(CONFIG_KVM_CLOCK)		+= kvmclock.o
 obj-$(CONFIG_PARAVIRT)		+= paravirt.o paravirt_patch_$(BITS).o
 
-ifdef CONFIG_INPUT_PCSPKR
-obj-y				+= pcspeaker.o
-endif
+obj-$(CONFIG_PCSPKR_PLATFORM)	+= pcspeaker.o
 
 obj-$(CONFIG_SCx200)		+= scx200.o
 scx200-y			+= scx200_32.o
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
index 22fab6c..7da00b7 100644
--- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S
+++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
@@ -12,11 +12,6 @@
 
 SECTIONS
 {
-	. = HEADER_OFFSET;
-	.header : {
-		 *(.header)
-	}
-
 	. = 0;
 	.text : {
 		 *(.text*)
@@ -50,6 +45,11 @@
 		__bss_end = .;
 	}
 
+	. = HEADER_OFFSET;
+	.header : {
+		*(.header)
+	}
+
 	. = ALIGN(16);
 	_end = .;
 
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c
index 238468a..c2e1ce3 100644
--- a/arch/x86/kernel/cpu/addon_cpuid_features.c
+++ b/arch/x86/kernel/cpu/addon_cpuid_features.c
@@ -6,6 +6,7 @@
 
 #include <linux/cpu.h>
 
+#include <asm/pat.h>
 #include <asm/processor.h>
 
 struct cpuid_bit {
@@ -48,3 +49,23 @@
 			set_cpu_cap(c, cb->feature);
 	}
 }
+
+#ifdef CONFIG_X86_PAT
+void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
+{
+	switch (c->x86_vendor) {
+	case X86_VENDOR_AMD:
+		if (c->x86 >= 0xf && c->x86 <= 0x11)
+			return;
+		break;
+	case X86_VENDOR_INTEL:
+		if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
+			return;
+		break;
+	}
+
+	pat_disable(cpu_has_pat ?
+		    "PAT disabled. Not yet verified on this CPU type." :
+		    "PAT not supported by CPU.");
+}
+#endif
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 35b4f6a..d0463a9 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -12,6 +12,7 @@
 #include <asm/mmu_context.h>
 #include <asm/mtrr.h>
 #include <asm/mce.h>
+#include <asm/pat.h>
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/mpspec.h>
 #include <asm/apic.h>
@@ -308,19 +309,6 @@
 
 	}
 
-	clear_cpu_cap(c, X86_FEATURE_PAT);
-
-	switch (c->x86_vendor) {
-	case X86_VENDOR_AMD:
-		if (c->x86 >= 0xf && c->x86 <= 0x11)
-			set_cpu_cap(c, X86_FEATURE_PAT);
-		break;
-	case X86_VENDOR_INTEL:
-		if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
-			set_cpu_cap(c, X86_FEATURE_PAT);
-		break;
-	}
-
 }
 
 /*
@@ -409,18 +397,6 @@
 		init_scattered_cpuid_features(c);
 	}
 
-	clear_cpu_cap(c, X86_FEATURE_PAT);
-
-	switch (c->x86_vendor) {
-	case X86_VENDOR_AMD:
-		if (c->x86 >= 0xf && c->x86 <= 0x11)
-			set_cpu_cap(c, X86_FEATURE_PAT);
-		break;
-	case X86_VENDOR_INTEL:
-		if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
-			set_cpu_cap(c, X86_FEATURE_PAT);
-		break;
-	}
 }
 
 static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
@@ -651,6 +627,7 @@
 		cpu_devs[cvdev->vendor] = cvdev->cpu_dev;
 
 	early_cpu_detect();
+	validate_pat_support(&boot_cpu_data);
 }
 
 /* Make sure %fs is initialized properly in idle threads */
diff --git a/arch/x86/kernel/geode_32.c b/arch/x86/kernel/geode_32.c
index 9dad6ca..e8edd63 100644
--- a/arch/x86/kernel/geode_32.c
+++ b/arch/x86/kernel/geode_32.c
@@ -161,6 +161,25 @@
 }
 EXPORT_SYMBOL_GPL(geode_gpio_setup_event);
 
+int geode_has_vsa2(void)
+{
+	static int has_vsa2 = -1;
+
+	if (has_vsa2 == -1) {
+		/*
+		 * The VSA has virtual registers that we can query for a
+		 * signature.
+		 */
+		outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
+		outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
+
+		has_vsa2 = (inw(VSA_VRC_DATA) == VSA_SIG);
+	}
+
+	return has_vsa2;
+}
+EXPORT_SYMBOL_GPL(geode_has_vsa2);
+
 static int __init geode_southbridge_init(void)
 {
 	if (!is_geode())
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index db6839b..e03cc95 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -450,7 +450,6 @@
 {
 	struct task_struct *tsk = current;
 
-	clear_fpu(tsk);
 	return __copy_from_user(&tsk->thread.xstate->fsave, buf,
 				sizeof(struct i387_fsave_struct));
 }
@@ -461,7 +460,6 @@
 	struct user_i387_ia32_struct env;
 	int err;
 
-	clear_fpu(tsk);
 	err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0],
 			       sizeof(struct i387_fxsave_struct));
 	/* mxcsr reserved bits must be masked to zero for security reasons */
@@ -478,6 +476,16 @@
 	int err;
 
 	if (HAVE_HWFP) {
+		struct task_struct *tsk = current;
+
+		clear_fpu(tsk);
+
+		if (!used_math()) {
+			err = init_fpu(tsk);
+			if (err)
+				return err;
+		}
+
 		if (cpu_has_fxsr)
 			err = restore_i387_fxsave(buf);
 		else
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 0c37f16..c5ef1af 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -385,11 +385,13 @@
 	if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory))
 		return memory;
 
-	if (!dev)
+	if (!dev) {
 		dev = &fallback_dev;
+		gfp |= GFP_DMA;
+	}
 	dma_mask = dev->coherent_dma_mask;
 	if (dma_mask == 0)
-		dma_mask = DMA_32BIT_MASK;
+		dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK;
 
 	/* Device not DMA able */
 	if (dev->dma_mask == NULL)
@@ -403,7 +405,7 @@
 	   larger than 16MB and in this case we have a chance of
 	   finding fitting memory in the next higher zone first. If
 	   not retry with true GFP_DMA. -AK */
-	if (dma_mask <= DMA_32BIT_MASK)
+	if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA))
 		gfp |= GFP_DMA32;
 #endif
 
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index fb03ef3..a7835f2 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1303,6 +1303,9 @@
 #define genregs32_get		genregs_get
 #define genregs32_set		genregs_set
 
+#define user_i387_ia32_struct	user_i387_struct
+#define user32_fxsr_struct	user_fxsr_struct
+
 #endif	/* CONFIG_X86_64 */
 
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
@@ -1315,13 +1318,13 @@
 	},
 	[REGSET_FP] = {
 		.core_note_type = NT_PRFPREG,
-		.n = sizeof(struct user_i387_struct) / sizeof(u32),
+		.n = sizeof(struct user_i387_ia32_struct) / sizeof(u32),
 		.size = sizeof(u32), .align = sizeof(u32),
 		.active = fpregs_active, .get = fpregs_get, .set = fpregs_set
 	},
 	[REGSET_XFP] = {
 		.core_note_type = NT_PRXFPREG,
-		.n = sizeof(struct user_i387_struct) / sizeof(u32),
+		.n = sizeof(struct user32_fxsr_struct) / sizeof(u32),
 		.size = sizeof(u32), .align = sizeof(u32),
 		.active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
 	},
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cc6f5eb..6f80b85 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -12,6 +12,7 @@
 #include <asm/mpspec.h>
 #include <asm/apicdef.h>
 
+#ifdef CONFIG_X86_LOCAL_APIC
 unsigned int num_processors;
 unsigned disabled_cpus __cpuinitdata;
 /* Processor that is doing the boot up */
@@ -23,8 +24,9 @@
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map;
+#endif
 
-#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_SMP)
+#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_X86_SMP)
 /*
  * Copy data used in early init routines from the initial arrays to the
  * per cpu data areas.  These arrays then become expendable and the
@@ -95,7 +97,7 @@
 
 	/* Copy section for each CPU (we discard the original) */
 	size = PERCPU_ENOUGH_ROOM;
-	printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n",
+	printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n",
 			  size);
 
 	for_each_possible_cpu(i) {
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index 2283422..2c5f8b2 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -127,7 +127,12 @@
 }, {
 	.name	= "keyboard",
 	.start	= 0x0060,
-	.end	= 0x006f,
+	.end	= 0x0060,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+	.name	= "keyboard",
+	.start	= 0x0064,
+	.end	= 0x0064,
 	.flags	= IORESOURCE_BUSY | IORESOURCE_IO
 }, {
 	.name	= "dma page reg",
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 22c14e2..6dff128 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -70,6 +70,7 @@
 #include <asm/ds.h>
 #include <asm/topology.h>
 #include <asm/trampoline.h>
+#include <asm/pat.h>
 
 #include <mach_apic.h>
 #ifdef CONFIG_PARAVIRT
@@ -128,7 +129,9 @@
 		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
 	{ .name = "timer1", .start = 0x50, .end = 0x53,
 		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
-	{ .name = "keyboard", .start = 0x60, .end = 0x6f,
+	{ .name = "keyboard", .start = 0x60, .end = 0x60,
+		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
+	{ .name = "keyboard", .start = 0x64, .end = 0x64,
 		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
 	{ .name = "dma page reg", .start = 0x80, .end = 0x8f,
 		.flags = IORESOURCE_BUSY | IORESOURCE_IO },
@@ -948,7 +951,7 @@
 static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
 {
 	if (c->x86 == 0x6 && c->x86_model >= 0xf)
-		set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
+		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 }
 
 static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
@@ -1063,25 +1066,19 @@
 	if (c->extended_cpuid_level >= 0x80000007)
 		c->x86_power = cpuid_edx(0x80000007);
 
-
-	clear_cpu_cap(c, X86_FEATURE_PAT);
-
 	switch (c->x86_vendor) {
 	case X86_VENDOR_AMD:
 		early_init_amd(c);
-		if (c->x86 >= 0xf && c->x86 <= 0x11)
-			set_cpu_cap(c, X86_FEATURE_PAT);
 		break;
 	case X86_VENDOR_INTEL:
 		early_init_intel(c);
-		if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
-			set_cpu_cap(c, X86_FEATURE_PAT);
 		break;
 	case X86_VENDOR_CENTAUR:
 		early_init_centaur(c);
 		break;
 	}
 
+	validate_pat_support(c);
 }
 
 /*
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 8f75893..0cb7aad 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -231,7 +231,8 @@
 	wmb();
 
 	/* Send a message to other CPUs */
-	if (cpus_equal(mask, allbutself))
+	if (cpus_equal(mask, allbutself) &&
+	    cpus_equal(cpu_online_map, cpu_callout_map))
 		send_IPI_allbutself(CALL_FUNCTION_VECTOR);
 	else
 		send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 6b087ab..3898849 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -86,6 +86,7 @@
 
 #ifdef CONFIG_X86_32
 u8 apicid_2_node[MAX_APICID];
+static int low_mappings;
 #endif
 
 /* State of each CPU */
@@ -326,6 +327,12 @@
 		enable_8259A_irq(0);
 	}
 
+#ifdef CONFIG_X86_32
+	while (low_mappings)
+		cpu_relax();
+	__flush_tlb_all();
+#endif
+
 	/* This must be done before setting cpu_online_map */
 	set_cpu_sibling_map(raw_smp_processor_id());
 	wmb();
@@ -1040,14 +1047,20 @@
 #ifdef CONFIG_X86_32
 	/* init low mem mapping */
 	clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-			min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
+		min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
 	flush_tlb_all();
-#endif
+	low_mappings = 1;
 
 	err = do_boot_cpu(apicid, cpu);
-	if (err < 0) {
+
+	zap_low_mappings();
+	low_mappings = 0;
+#else
+	err = do_boot_cpu(apicid, cpu);
+#endif
+	if (err) {
 		Dprintk("do_boot_cpu failed %d\n", err);
-		return err;
+		return -EIO;
 	}
 
 	/*
@@ -1259,9 +1272,6 @@
 	setup_ioapic_dest();
 #endif
 	check_nmi_watchdog();
-#ifdef CONFIG_X86_32
-	zap_low_mappings();
-#endif
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 58882f9..f6c05d0 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -2,6 +2,7 @@
    All C exports should go in the respective C files. */
 
 #include <linux/module.h>
+#include <net/checksum.h>
 #include <linux/smp.h>
 
 #include <asm/processor.h>
@@ -29,6 +30,8 @@
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(clear_page);
 
+EXPORT_SYMBOL(csum_partial);
+
 /*
  * Export string functions. We normally rely on gcc builtin for most of these,
  * but gcc sometimes decides not to inline them.
diff --git a/arch/x86/lib/csum-partial_64.c b/arch/x86/lib/csum-partial_64.c
index bc503f5..bf51144 100644
--- a/arch/x86/lib/csum-partial_64.c
+++ b/arch/x86/lib/csum-partial_64.c
@@ -136,8 +136,6 @@
 						(__force u32)sum);
 }
 
-EXPORT_SYMBOL(csum_partial);
-
 /*
  * this routine is used for miscellaneous IP-like checksums, mainly
  * in icmp.c
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index de236e4..ec30d10 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -438,8 +438,6 @@
 {
 	int i;
 
-	save_pg_dir();
-
 	/*
 	 * Zap initial low-memory mappings.
 	 *
@@ -663,16 +661,8 @@
 		test_wp_bit();
 
 	cpa_init();
-
-	/*
-	 * Subtle. SMP is doing it's boot stuff late (because it has to
-	 * fork idle threads) - but it also needs low mappings for the
-	 * protected-mode entry to work. We zap these entries only after
-	 * the WP-bit has been tested.
-	 */
-#ifndef CONFIG_SMP
+	save_pg_dir();
 	zap_low_mappings();
-#endif
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 277446c..bcb1a8e 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -25,31 +25,24 @@
 #include <asm/mtrr.h>
 #include <asm/io.h>
 
-int pat_wc_enabled = 1;
+#ifdef CONFIG_X86_PAT
+int __read_mostly pat_wc_enabled = 1;
 
-static u64 __read_mostly boot_pat_state;
+void __init pat_disable(char *reason)
+{
+	pat_wc_enabled = 0;
+	printk(KERN_INFO "%s\n", reason);
+}
 
 static int nopat(char *str)
 {
-	pat_wc_enabled = 0;
-	printk(KERN_INFO "x86: PAT support disabled.\n");
-
+	pat_disable("PAT support disabled.");
 	return 0;
 }
 early_param("nopat", nopat);
+#endif
 
-static int pat_known_cpu(void)
-{
-	if (!pat_wc_enabled)
-		return 0;
-
-	if (cpu_has_pat)
-		return 1;
-
-	pat_wc_enabled = 0;
-	printk(KERN_INFO "CPU and/or kernel does not support PAT.\n");
-	return 0;
-}
+static u64 __read_mostly boot_pat_state;
 
 enum {
 	PAT_UC = 0,		/* uncached */
@@ -66,17 +59,19 @@
 {
 	u64 pat;
 
-#ifndef CONFIG_X86_PAT
-	nopat(NULL);
-#endif
-
-	/* Boot CPU enables PAT based on CPU feature */
-	if (!smp_processor_id() && !pat_known_cpu())
+	if (!pat_wc_enabled)
 		return;
 
-	/* APs enable PAT iff boot CPU has enabled it before */
-	if (smp_processor_id() && !pat_wc_enabled)
-		return;
+	/* Paranoia check. */
+	if (!cpu_has_pat) {
+		printk(KERN_ERR "PAT enabled, but CPU feature cleared\n");
+		/*
+		 * Panic if this happens on the secondary CPU, and we
+		 * switched to PAT on the boot CPU. We have no way to
+		 * undo PAT.
+		*/
+		BUG_ON(boot_pat_state);
+	}
 
 	/* Set PWT to Write-Combining. All other bits stay the same */
 	/*
@@ -95,9 +90,8 @@
 	      PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC);
 
 	/* Boot CPU check */
-	if (!smp_processor_id()) {
+	if (!boot_pat_state)
 		rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
-	}
 
 	wrmsrl(MSR_IA32_CR_PAT, pat);
 	printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n",
@@ -561,7 +555,7 @@
 		"%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
 			current->comm, current->pid,
 			cattr_name(flags),
-			offset, offset + size);
+			offset, (unsigned long long)(offset + size));
 		return 0;
 	}
 
@@ -582,7 +576,7 @@
 		"%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n",
 			current->comm, current->pid,
 			cattr_name(want_flags),
-			addr, addr + size,
+			addr, (unsigned long long)(addr + size),
 			cattr_name(flags));
 	}
 }
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index 9ee007b..369cf06 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -172,10 +172,3 @@
 	__FIXADDR_TOP = -reserve - PAGE_SIZE;
 	__VMALLOC_RESERVE += reserve;
 }
-
-int pmd_bad(pmd_t pmd)
-{
-	WARN_ON_ONCE(pmd_bad_v1(pmd) != pmd_bad_v2(pmd));
-
-	return pmd_bad_v1(pmd);
-}
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 1a9c0c6..d95de2f 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -6,45 +6,6 @@
 #include <asm/numa.h>
 #include "pci.h"
 
-static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
-{
-	pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
-	printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
-	return 0;
-}
-
-static struct dmi_system_id acpi_pciprobe_dmi_table[] __devinitdata = {
-/*
- * Systems where PCI IO resource ISA alignment can be skipped
- * when the ISA enable bit in the bridge control is not set
- */
-	{
-		.callback = can_skip_ioresource_align,
-		.ident = "IBM System x3800",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
-		},
-	},
-	{
-		.callback = can_skip_ioresource_align,
-		.ident = "IBM System x3850",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
-		},
-	},
-	{
-		.callback = can_skip_ioresource_align,
-		.ident = "IBM System x3950",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
-		},
-	},
-	{}
-};
-
 struct pci_root_info {
 	char *name;
 	unsigned int res_num;
@@ -196,8 +157,6 @@
 	int pxm;
 #endif
 
-	dmi_check_system(acpi_pciprobe_dmi_table);
-
 	if (domain && !pci_domains_supported) {
 		printk(KERN_WARNING "PCI: Multiple domains not supported "
 		       "(dom %d, bus %d)\n", domain, busnum);
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 2a4d751..8545c8a 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -77,17 +77,48 @@
  */
 DEFINE_SPINLOCK(pci_config_lock);
 
-static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
+static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
 {
-	struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
+	pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
+	printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
+	return 0;
+}
 
-	if (rom_r->parent)
-		return;
-	if (rom_r->start)
-		/* we deal with BIOS assigned ROM later */
-		return;
-	if (!(pci_probe & PCI_ASSIGN_ROMS))
-		rom_r->start = rom_r->end = rom_r->flags = 0;
+static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = {
+/*
+ * Systems where PCI IO resource ISA alignment can be skipped
+ * when the ISA enable bit in the bridge control is not set
+ */
+	{
+		.callback = can_skip_ioresource_align,
+		.ident = "IBM System x3800",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
+		},
+	},
+	{
+		.callback = can_skip_ioresource_align,
+		.ident = "IBM System x3850",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
+		},
+	},
+	{
+		.callback = can_skip_ioresource_align,
+		.ident = "IBM System x3950",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
+		},
+	},
+	{}
+};
+
+void __init dmi_check_skip_isa_align(void)
+{
+	dmi_check_system(can_skip_pciprobe_dmi_table);
 }
 
 /*
@@ -97,11 +128,7 @@
 
 void __devinit  pcibios_fixup_bus(struct pci_bus *b)
 {
-	struct pci_dev *dev;
-
 	pci_read_bridge_bases(b);
-	list_for_each_entry(dev, &b->devices, bus_list)
-		pcibios_fixup_device_resources(dev);
 }
 
 /*
@@ -318,13 +345,16 @@
 	{}
 };
 
+void __init dmi_check_pciprobe(void)
+{
+	dmi_check_system(pciprobe_dmi_table);
+}
+
 struct pci_bus * __devinit pcibios_scan_root(int busnum)
 {
 	struct pci_bus *bus = NULL;
 	struct pci_sysdata *sd;
 
-	dmi_check_system(pciprobe_dmi_table);
-
 	while ((bus = pci_find_next_bus(bus)) != NULL) {
 		if (bus->number == busnum) {
 			/* Already scanned */
@@ -462,6 +492,9 @@
 	} else if (!strcmp(str, "routeirq")) {
 		pci_routeirq = 1;
 		return NULL;
+	} else if (!strcmp(str, "skip_isa_align")) {
+		pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
+		return NULL;
 	}
 	return str;
 }
@@ -489,7 +522,7 @@
 		pcibios_disable_irq(dev);
 }
 
-struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
+struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
 {
 	struct pci_bus *bus = NULL;
 	struct pci_sysdata *sd;
@@ -512,7 +545,7 @@
 	return bus;
 }
 
-struct pci_bus *pci_scan_bus_with_sysdata(int busno)
+struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno)
 {
 	return pci_scan_bus_on_node(busno, &pci_root_ops, -1);
 }
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index b60b2ab..ff3a6a3 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -502,7 +502,7 @@
  */
 static void fam10h_pci_cfg_space_size(struct pci_dev *dev)
 {
-	dev->cfg_size = pci_cfg_space_size_ext(dev, 0);
+	dev->cfg_size = pci_cfg_space_size_ext(dev);
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size);
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 8af0f0b..10fb308 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -301,15 +301,13 @@
 	prot = pgprot_val(vma->vm_page_prot);
 	if (pat_wc_enabled && write_combine)
 		prot |= _PAGE_CACHE_WC;
-	else if (pat_wc_enabled)
+	else if (pat_wc_enabled || boot_cpu_data.x86 > 3)
 		/*
 		 * ioremap() and ioremap_nocache() defaults to UC MINUS for now.
 		 * To avoid attribute conflicts, request UC MINUS here
 		 * aswell.
 		 */
 		prot |= _PAGE_CACHE_UC_MINUS;
-	else if (boot_cpu_data.x86 > 3)
-		prot |= _PAGE_CACHE_UC;
 
 	vma->vm_page_prot = __pgprot(prot);
 
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index dd30c60..e70b9c5 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -33,6 +33,10 @@
 		printk(KERN_ERR
 		"PCI: Fatal: No config space access function found\n");
 
+	dmi_check_pciprobe();
+
+	dmi_check_skip_isa_align();
+
 	return 0;
 }
 arch_initcall(pci_access_init);
diff --git a/arch/x86/pci/k8-bus_64.c b/arch/x86/pci/k8-bus_64.c
index ab6d4b1..5c2799c 100644
--- a/arch/x86/pci/k8-bus_64.c
+++ b/arch/x86/pci/k8-bus_64.c
@@ -504,14 +504,6 @@
 		}
 	}
 
-#ifdef CONFIG_NUMA
-	for (i = 0; i < BUS_NR; i++) {
-		node = mp_bus_to_node[i];
-		if (node >= 0)
-			printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node);
-	}
-#endif
-
 	for (i = 0; i < pci_root_num; i++) {
 		int res_num;
 		int busnum;
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index c58805a..f3972b1 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -38,6 +38,9 @@
 	pci_dmi_bf,
 };
 
+extern void __init dmi_check_pciprobe(void);
+extern void __init dmi_check_skip_isa_align(void);
+
 /* pci-i386.c */
 
 extern unsigned int pcibios_max_latency;
diff --git a/block/blk-core.c b/block/blk-core.c
index b754a4a..6a9cc0d 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -54,15 +54,16 @@
 
 static void drive_stat_acct(struct request *rq, int new_io)
 {
+	struct hd_struct *part;
 	int rw = rq_data_dir(rq);
 
 	if (!blk_fs_request(rq) || !rq->rq_disk)
 		return;
 
-	if (!new_io) {
-		__all_stat_inc(rq->rq_disk, merges[rw], rq->sector);
-	} else {
-		struct hd_struct *part = get_part(rq->rq_disk, rq->sector);
+	part = get_part(rq->rq_disk, rq->sector);
+	if (!new_io)
+		__all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector);
+	else {
 		disk_round_stats(rq->rq_disk);
 		rq->rq_disk->in_flight++;
 		if (part) {
@@ -253,9 +254,11 @@
  **/
 void generic_unplug_device(struct request_queue *q)
 {
-	spin_lock_irq(q->queue_lock);
-	__generic_unplug_device(q);
-	spin_unlock_irq(q->queue_lock);
+	if (blk_queue_plugged(q)) {
+		spin_lock_irq(q->queue_lock);
+		__generic_unplug_device(q);
+		spin_unlock_irq(q->queue_lock);
+	}
 }
 EXPORT_SYMBOL(generic_unplug_device);
 
@@ -479,6 +482,7 @@
 	kobject_init(&q->kobj, &blk_queue_ktype);
 
 	mutex_init(&q->sysfs_lock);
+	spin_lock_init(&q->__queue_lock);
 
 	return q;
 }
@@ -541,10 +545,8 @@
 	 * if caller didn't supply a lock, they get per-queue locking with
 	 * our embedded lock
 	 */
-	if (!lock) {
-		spin_lock_init(&q->__queue_lock);
+	if (!lock)
 		lock = &q->__queue_lock;
-	}
 
 	q->request_fn		= rfn;
 	q->prep_rq_fn		= NULL;
@@ -1536,10 +1538,11 @@
 	}
 
 	if (blk_fs_request(req) && req->rq_disk) {
+		struct hd_struct *part = get_part(req->rq_disk, req->sector);
 		const int rw = rq_data_dir(req);
 
-		all_stat_add(req->rq_disk, sectors[rw],
-			     nr_bytes >> 9, req->sector);
+		all_stat_add(req->rq_disk, part, sectors[rw],
+				nr_bytes >> 9, req->sector);
 	}
 
 	total_bytes = bio_nbytes = 0;
@@ -1725,8 +1728,8 @@
 		const int rw = rq_data_dir(req);
 		struct hd_struct *part = get_part(disk, req->sector);
 
-		__all_stat_inc(disk, ios[rw], req->sector);
-		__all_stat_add(disk, ticks[rw], duration, req->sector);
+		__all_stat_inc(disk, part, ios[rw], req->sector);
+		__all_stat_add(disk, part, ticks[rw], duration, req->sector);
 		disk_round_stats(disk);
 		disk->in_flight--;
 		if (part) {
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index e34df7c..012f065 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -41,8 +41,8 @@
 		rcu_read_lock();
 		if (ioc->aic && ioc->aic->dtor)
 			ioc->aic->dtor(ioc->aic);
-		rcu_read_unlock();
 		cfq_dtor(ioc);
+		rcu_read_unlock();
 
 		kmem_cache_free(iocontext_cachep, ioc);
 		return 1;
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 73b2356..651136a 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -149,9 +149,9 @@
 static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio,
 				 struct bio *nxt)
 {
-	if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
+	if (!bio_flagged(bio, BIO_SEG_VALID))
 		blk_recount_segments(q, bio);
-	if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID)))
+	if (!bio_flagged(nxt, BIO_SEG_VALID))
 		blk_recount_segments(q, nxt);
 	if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) ||
 	    BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size))
@@ -312,9 +312,9 @@
 			q->last_merge = NULL;
 		return 0;
 	}
-	if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID)))
+	if (!bio_flagged(req->biotail, BIO_SEG_VALID))
 		blk_recount_segments(q, req->biotail);
-	if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
+	if (!bio_flagged(bio, BIO_SEG_VALID))
 		blk_recount_segments(q, bio);
 	len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size;
 	if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio))
@@ -352,9 +352,9 @@
 		return 0;
 	}
 	len = bio->bi_hw_back_size + req->bio->bi_hw_front_size;
-	if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
+	if (!bio_flagged(bio, BIO_SEG_VALID))
 		blk_recount_segments(q, bio);
-	if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID)))
+	if (!bio_flagged(req->bio, BIO_SEG_VALID))
 		blk_recount_segments(q, req->bio);
 	if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) &&
 	    !BIOVEC_VIRT_OVERSIZE(len)) {
diff --git a/block/blk-settings.c b/block/blk-settings.c
index bb93d4c..8dd8641 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -286,8 +286,14 @@
 	t->max_hw_segments = min(t->max_hw_segments, b->max_hw_segments);
 	t->max_segment_size = min(t->max_segment_size, b->max_segment_size);
 	t->hardsect_size = max(t->hardsect_size, b->hardsect_size);
-	if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
+	if (!t->queue_lock)
+		WARN_ON_ONCE(1);
+	else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
+		unsigned long flags;
+		spin_lock_irqsave(t->queue_lock, flags);
 		queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
+		spin_unlock_irqrestore(t->queue_lock, flags);
+	}
 }
 EXPORT_SYMBOL(blk_queue_stack_limits);
 
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index e85c401..304ec73 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -146,11 +146,13 @@
 	unsigned long nm;
 	ssize_t ret = queue_var_store(&nm, page, count);
 
+	spin_lock_irq(q->queue_lock);
 	if (nm)
-	       set_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags);
+		queue_flag_set(QUEUE_FLAG_NOMERGES, q);
 	else
-	       clear_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags);
+		queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
 
+	spin_unlock_irq(q->queue_lock);
 	return ret;
 }
 
diff --git a/block/blk-tag.c b/block/blk-tag.c
index de64e04..32667be 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -70,7 +70,7 @@
 	__blk_free_tags(bqt);
 
 	q->queue_tags = NULL;
-	queue_flag_clear(QUEUE_FLAG_QUEUED, q);
+	queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
 }
 
 /**
@@ -98,7 +98,7 @@
  **/
 void blk_queue_free_tags(struct request_queue *q)
 {
-	queue_flag_clear(QUEUE_FLAG_QUEUED, q);
+	queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
 }
 EXPORT_SYMBOL(blk_queue_free_tags);
 
@@ -171,6 +171,9 @@
  * @q:  the request queue for the device
  * @depth:  the maximum queue depth supported
  * @tags: the tag to use
+ *
+ * Queue lock must be held here if the function is called to resize an
+ * existing map.
  **/
 int blk_queue_init_tags(struct request_queue *q, int depth,
 			struct blk_queue_tag *tags)
@@ -197,7 +200,7 @@
 	 * assign it, all done
 	 */
 	q->queue_tags = tags;
-	queue_flag_set(QUEUE_FLAG_QUEUED, q);
+	queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, q);
 	INIT_LIST_HEAD(&q->tag_busy_list);
 	return 0;
 fail:
diff --git a/block/blktrace.c b/block/blktrace.c
index 568588c..b2cbb4e 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -476,7 +476,7 @@
 
 	switch (cmd) {
 	case BLKTRACESETUP:
-		strcpy(b, bdevname(bdev, b));
+		bdevname(bdev, b);
 		ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
 		break;
 	case BLKTRACESTART:
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index f4e1006..b399c62 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1142,6 +1142,17 @@
 	kmem_cache_free(cfq_pool, cfqq);
 }
 
+static void
+__call_for_each_cic(struct io_context *ioc,
+		    void (*func)(struct io_context *, struct cfq_io_context *))
+{
+	struct cfq_io_context *cic;
+	struct hlist_node *n;
+
+	hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
+		func(ioc, cic);
+}
+
 /*
  * Call func for each cic attached to this ioc.
  */
@@ -1149,12 +1160,8 @@
 call_for_each_cic(struct io_context *ioc,
 		  void (*func)(struct io_context *, struct cfq_io_context *))
 {
-	struct cfq_io_context *cic;
-	struct hlist_node *n;
-
 	rcu_read_lock();
-	hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
-		func(ioc, cic);
+	__call_for_each_cic(ioc, func);
 	rcu_read_unlock();
 }
 
@@ -1198,7 +1205,7 @@
 	 * should be ok to iterate over the known list, we will see all cic's
 	 * since no new ones are added.
 	 */
-	call_for_each_cic(ioc, cic_free_func);
+	__call_for_each_cic(ioc, cic_free_func);
 }
 
 static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
@@ -1296,10 +1303,10 @@
 		printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class);
 	case IOPRIO_CLASS_NONE:
 		/*
-		 * no prio set, place us in the middle of the BE classes
+		 * no prio set, inherit CPU scheduling settings
 		 */
 		cfqq->ioprio = task_nice_ioprio(tsk);
-		cfqq->ioprio_class = IOPRIO_CLASS_BE;
+		cfqq->ioprio_class = task_nice_ioclass(tsk);
 		break;
 	case IOPRIO_CLASS_RT:
 		cfqq->ioprio = task_ioprio(ioc);
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index c70d0b6..c23177e 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -555,7 +555,7 @@
 	if (copy_from_user(&cbuts, arg, sizeof(cbuts)))
 		return -EFAULT;
 
-	strcpy(b, bdevname(bdev, b));
+	bdevname(bdev, b);
 
 	buts = (struct blk_user_trace_setup) {
 		.act_mask = cbuts.act_mask,
diff --git a/block/genhd.c b/block/genhd.c
index fda9c7a..129ad93 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -653,7 +653,7 @@
 EXPORT_SYMBOL_GPL(genhd_media_change_notify);
 #endif  /*  0  */
 
-dev_t blk_lookup_devt(const char *name)
+dev_t blk_lookup_devt(const char *name, int part)
 {
 	struct device *dev;
 	dev_t devt = MKDEV(0, 0);
@@ -661,7 +661,11 @@
 	mutex_lock(&block_class_lock);
 	list_for_each_entry(dev, &block_class.devices, node) {
 		if (strcmp(dev->bus_id, name) == 0) {
-			devt = dev->devt;
+			struct gendisk *disk = dev_to_disk(dev);
+
+			if (part < disk->minors)
+				devt = MKDEV(MAJOR(dev->devt),
+					     MINOR(dev->devt) + part);
 			break;
 		}
 	}
@@ -669,7 +673,6 @@
 
 	return devt;
 }
-
 EXPORT_SYMBOL(blk_lookup_devt);
 
 struct gendisk *alloc_disk(int minors)
diff --git a/crypto/hmac.c b/crypto/hmac.c
index b60c3c7..14c6351 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -57,14 +57,35 @@
 	if (keylen > bs) {
 		struct hash_desc desc;
 		struct scatterlist tmp;
+		int tmplen;
 		int err;
 
 		desc.tfm = tfm;
 		desc.flags = crypto_hash_get_flags(parent);
 		desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP;
-		sg_init_one(&tmp, inkey, keylen);
 
-		err = crypto_hash_digest(&desc, &tmp, keylen, digest);
+		err = crypto_hash_init(&desc);
+		if (err)
+			return err;
+
+		tmplen = bs * 2 + ds;
+		sg_init_one(&tmp, ipad, tmplen);
+
+		for (; keylen > tmplen; inkey += tmplen, keylen -= tmplen) {
+			memcpy(ipad, inkey, tmplen);
+			err = crypto_hash_update(&desc, &tmp, tmplen);
+			if (err)
+				return err;
+		}
+
+		if (keylen) {
+			memcpy(ipad, inkey, keylen);
+			err = crypto_hash_update(&desc, &tmp, keylen);
+			if (err)
+				return err;
+		}
+
+		err = crypto_hash_final(&desc, digest);
 		if (err)
 			return err;
 
diff --git a/drivers/accessibility/Kconfig b/drivers/accessibility/Kconfig
index 1264c4b..ef3b65b 100644
--- a/drivers/accessibility/Kconfig
+++ b/drivers/accessibility/Kconfig
@@ -1,7 +1,17 @@
 menuconfig ACCESSIBILITY
 	bool "Accessibility support"
 	---help---
-	  Enable a submenu where accessibility items may be enabled.
+	  Accessibility handles all special kinds of hardware devices or
+	  software adapters which help people with disabilities (e.g.
+	  blindness) to use computers.
+
+	  That includes braille devices, speech synthesis, keyboard
+	  remapping, etc.
+
+	  Say Y here to get to see options for accessibility.
+	  This option alone does not add any kernel code.
+
+	  If you say N, all options in this submenu will be skipped and disabled.
 
 	  If unsure, say N.
 
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 1c11df9..9bf2986 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -205,8 +205,8 @@
 	  If unsure, say N.
 
 config SATA_INIC162X
-	tristate "Initio 162x SATA support (HIGHLY EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
+	tristate "Initio 162x SATA support"
+	depends on PCI
 	help
 	  This option enables support for Initio 162x Serial ATA.
 
@@ -697,6 +697,15 @@
 
 	  If unsure, say N.
 
+config PATA_SCH
+	tristate "Intel SCH PATA support"
+	depends on PCI
+	help
+	  This option enables support for Intel SCH PATA on the Intel
+	  SCH (US15W, US15L, UL11L) series host controllers.
+
+	  If unsure, say N.
+
 config PATA_BF54X
 	tristate "Blackfin 54x ATAPI support"
 	depends on BF542 || BF548 || BF549
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index b693d82..674965f 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -67,6 +67,7 @@
 obj-$(CONFIG_PATA_TRIFLEX)	+= pata_triflex.o
 obj-$(CONFIG_PATA_IXP4XX_CF)	+= pata_ixp4xx_cf.o
 obj-$(CONFIG_PATA_SCC)		+= pata_scc.o
+obj-$(CONFIG_PATA_SCH)		+= pata_sch.o
 obj-$(CONFIG_PATA_BF54X)	+= pata_bf54x.o
 obj-$(CONFIG_PATA_PLATFORM)	+= pata_platform.o
 obj-$(CONFIG_PATA_OF_PLATFORM)	+= pata_of_platform.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 8cace9a..97f83fb 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1267,9 +1267,7 @@
 	void __iomem *port_mmio = ahci_port_base(link->ap);
 	u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF;
 
-	if (!(status & ATA_BUSY))
-		return 1;
-	return 0;
+	return ata_check_ready(status);
 }
 
 static int ahci_softreset(struct ata_link *link, unsigned int *class,
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 47aeccd..75a406f 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -152,6 +152,12 @@
 	if (dev->vendor == PCI_VENDOR_ID_AL)
 		ata_pci_bmdma_clear_simplex(dev);
 
+	if (dev->vendor == PCI_VENDOR_ID_ATI) {
+		int rc = pcim_enable_device(dev);
+		if (rc < 0)
+			return rc;
+		pcim_pin_device(dev);
+	}
 	return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL);
 }
 
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index ea2c764..a9027b8 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1348,6 +1348,8 @@
 {
 	struct pci_dev *pdev = to_pci_dev(host->dev);
 	struct piix_host_priv *hpriv = host->private_data;
+	struct ata_device *dev0 = &host->ports[0]->link.device[0];
+	u32 scontrol;
 	int i;
 
 	/* check for availability */
@@ -1366,6 +1368,29 @@
 		return;
 
 	hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
+
+	/* SCR access via SIDPR doesn't work on some configurations.
+	 * Give it a test drive by inhibiting power save modes which
+	 * we'll do anyway.
+	 */
+	scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+
+	/* if IPM is already 3, SCR access is probably working.  Don't
+	 * un-inhibit power save modes as BIOS might have inhibited
+	 * them for a reason.
+	 */
+	if ((scontrol & 0xf00) != 0x300) {
+		scontrol |= 0x300;
+		piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
+		scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+
+		if ((scontrol & 0xf00) != 0x300) {
+			dev_printk(KERN_INFO, host->dev, "SCR access via "
+				   "SIDPR is available but doesn't work\n");
+			return;
+		}
+	}
+
 	host->ports[0]->ops = &piix_sidpr_sata_ops;
 	host->ports[1]->ops = &piix_sidpr_sata_ops;
 }
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3bc4885..927b692 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6292,6 +6292,7 @@
 EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
 EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
 EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
+EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error);
 EXPORT_SYMBOL_GPL(ata_do_eh);
 EXPORT_SYMBOL_GPL(ata_std_error_handler);
 
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 61dcd00..62e0331 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1357,7 +1357,7 @@
  *	LOCKING:
  *	Kernel thread context (may sleep).
  */
-static void ata_eh_analyze_ncq_error(struct ata_link *link)
+void ata_eh_analyze_ncq_error(struct ata_link *link)
 {
 	struct ata_port *ap = link->ap;
 	struct ata_eh_context *ehc = &link->eh_context;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 2ec65a8..3c2d228 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -314,11 +314,7 @@
 {
 	u8 status = link->ap->ops->sff_check_status(link->ap);
 
-	if (!(status & ATA_BUSY))
-		return 1;
-	if (status == 0xff)
-		return -ENODEV;
-	return 0;
+	return ata_check_ready(status);
 }
 
 /**
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index c5f91e6..fbe6057 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -259,6 +259,12 @@
 		.port_ops	= &pacpi_ops,
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
+	if (pdev->vendor == PCI_VENDOR_ID_ATI) {
+		int rc = pcim_enable_device(pdev);
+		if (rc < 0)
+			return rc;
+		pcim_pin_device(pdev);
+	}
 	return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL);
 }
 
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c
new file mode 100644
index 0000000..c8cc027
--- /dev/null
+++ b/drivers/ata/pata_sch.c
@@ -0,0 +1,206 @@
+/*
+ *  pata_sch.c - Intel SCH PATA controllers
+ *
+ *  Copyright (c) 2008 Alek Du <alek.du@intel.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ *  Supports:
+ *    Intel SCH (AF82US15W, AF82US15L, AF82UL11L) chipsets -- see spec at:
+ *    http://download.intel.com/design/chipsets/embedded/datashts/319537.pdf
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/dmi.h>
+
+#define DRV_NAME	"pata_sch"
+#define DRV_VERSION	"0.2"
+
+/* see SCH datasheet page 351 */
+enum {
+	D0TIM	= 0x80,		/* Device 0 Timing Register */
+	D1TIM	= 0x84,		/* Device 1 Timing Register */
+	PM	= 0x07,		/* PIO Mode Bit Mask */
+	MDM	= (0x03 << 8),	/* Multi-word DMA Mode Bit Mask */
+	UDM	= (0x07 << 16), /* Ultra DMA Mode Bit Mask */
+	PPE	= (1 << 30),	/* Prefetch/Post Enable */
+	USD	= (1 << 31),	/* Use Synchronous DMA */
+};
+
+static int sch_init_one(struct pci_dev *pdev,
+			 const struct pci_device_id *ent);
+static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev);
+static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev);
+
+static const struct pci_device_id sch_pci_tbl[] = {
+	/* Intel SCH PATA Controller */
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_IDE), 0 },
+	{ }	/* terminate list */
+};
+
+static struct pci_driver sch_pci_driver = {
+	.name			= DRV_NAME,
+	.id_table		= sch_pci_tbl,
+	.probe			= sch_init_one,
+	.remove			= ata_pci_remove_one,
+#ifdef CONFIG_PM
+	.suspend		= ata_pci_device_suspend,
+	.resume			= ata_pci_device_resume,
+#endif
+};
+
+static struct scsi_host_template sch_sht = {
+	ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations sch_pata_ops = {
+	.inherits		= &ata_bmdma_port_ops,
+	.cable_detect		= ata_cable_unknown,
+	.set_piomode		= sch_set_piomode,
+	.set_dmamode		= sch_set_dmamode,
+};
+
+static struct ata_port_info sch_port_info = {
+	.flags		= 0,
+	.pio_mask	= ATA_PIO4,   /* pio0-4 */
+	.mwdma_mask	= ATA_MWDMA2, /* mwdma0-2 */
+	.udma_mask	= ATA_UDMA5,  /* udma0-5 */
+	.port_ops	= &sch_pata_ops,
+};
+
+MODULE_AUTHOR("Alek Du <alek.du@intel.com>");
+MODULE_DESCRIPTION("SCSI low-level driver for Intel SCH PATA controllers");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, sch_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+/**
+ *	sch_set_piomode - Initialize host controller PATA PIO timings
+ *	@ap: Port whose timings we are configuring
+ *	@adev: ATA device
+ *
+ *	Set PIO mode for device, in host controller PCI config space.
+ *
+ *	LOCKING:
+ *	None (inherited from caller).
+ */
+
+static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+	unsigned int pio	= adev->pio_mode - XFER_PIO_0;
+	struct pci_dev *dev	= to_pci_dev(ap->host->dev);
+	unsigned int port	= adev->devno ? D1TIM : D0TIM;
+	unsigned int data;
+
+	pci_read_config_dword(dev, port, &data);
+	/* see SCH datasheet page 351 */
+	/* set PIO mode */
+	data &= ~(PM | PPE);
+	data |= pio;
+	/* enable PPE for block device */
+	if (adev->class == ATA_DEV_ATA)
+		data |= PPE;
+	pci_write_config_dword(dev, port, data);
+}
+
+/**
+ *	sch_set_dmamode - Initialize host controller PATA DMA timings
+ *	@ap: Port whose timings we are configuring
+ *	@adev: ATA device
+ *
+ *	Set MW/UDMA mode for device, in host controller PCI config space.
+ *
+ *	LOCKING:
+ *	None (inherited from caller).
+ */
+
+static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+	unsigned int dma_mode	= adev->dma_mode;
+	struct pci_dev *dev	= to_pci_dev(ap->host->dev);
+	unsigned int port	= adev->devno ? D1TIM : D0TIM;
+	unsigned int data;
+
+	pci_read_config_dword(dev, port, &data);
+	/* see SCH datasheet page 351 */
+	if (dma_mode >= XFER_UDMA_0) {
+		/* enable Synchronous DMA mode */
+		data |= USD;
+		data &= ~UDM;
+		data |= (dma_mode - XFER_UDMA_0) << 16;
+	} else { /* must be MWDMA mode, since we masked SWDMA already */
+		data &= ~(USD | MDM);
+		data |= (dma_mode - XFER_MW_DMA_0) << 8;
+	}
+	pci_write_config_dword(dev, port, data);
+}
+
+/**
+ *	sch_init_one - Register SCH ATA PCI device with kernel services
+ *	@pdev: PCI device to register
+ *	@ent: Entry in sch_pci_tbl matching with @pdev
+ *
+ *	LOCKING:
+ *	Inherited from PCI layer (may sleep).
+ *
+ *	RETURNS:
+ *	Zero on success, or -ERRNO value.
+ */
+
+static int __devinit sch_init_one(struct pci_dev *pdev,
+				   const struct pci_device_id *ent)
+{
+	static int printed_version;
+	const struct ata_port_info *ppi[] = { &sch_port_info, NULL };
+	struct ata_host *host;
+	int rc;
+
+	if (!printed_version++)
+		dev_printk(KERN_DEBUG, &pdev->dev,
+			   "version " DRV_VERSION "\n");
+
+	/* enable device and prepare host */
+	rc = pcim_enable_device(pdev);
+	if (rc)
+		return rc;
+	rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+	if (rc)
+		return rc;
+	pci_set_master(pdev);
+	return ata_pci_sff_activate_host(host, ata_sff_interrupt, &sch_sht);
+}
+
+static int __init sch_init(void)
+{
+	return pci_register_driver(&sch_pci_driver);
+}
+
+static void __exit sch_exit(void)
+{
+	pci_unregister_driver(&sch_pci_driver);
+}
+
+module_init(sch_init);
+module_exit(sch_exit);
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index d27bb9a..3ead02f 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -10,13 +10,33 @@
  * right.  Documentation is available at initio's website but it only
  * documents registers (not programming model).
  *
- * - ATA disks work.
- * - Hotplug works.
- * - ATAPI read works but burning doesn't.  This thing is really
- *   peculiar about ATAPI and I couldn't figure out how ATAPI PIO and
- *   ATAPI DMA WRITE should be programmed.  If you've got a clue, be
- *   my guest.
- * - Both STR and STD work.
+ * This driver has interesting history.  The first version was written
+ * from the documentation and a 2.4 IDE driver posted on a Taiwan
+ * company, which didn't use any IDMA features and couldn't handle
+ * LBA48.  The resulting driver couldn't handle LBA48 devices either
+ * making it pretty useless.
+ *
+ * After a while, initio picked the driver up, renamed it to
+ * sata_initio162x, updated it to use IDMA for ATA DMA commands and
+ * posted it on their website.  It only used ATA_PROT_DMA for IDMA and
+ * attaching both devices and issuing IDMA and !IDMA commands
+ * simultaneously broke it due to PIRQ masking interaction but it did
+ * show how to use the IDMA (ADMA + some initio specific twists)
+ * engine.
+ *
+ * Then, I picked up their changes again and here's the usable driver
+ * which uses IDMA for everything.  Everything works now including
+ * LBA48, CD/DVD burning, suspend/resume and hotplug.  There are some
+ * issues tho.  Result Tf is not resported properly, NCQ isn't
+ * supported yet and CD/DVD writing works with DMA assisted PIO
+ * protocol (which, for native SATA devices, shouldn't cause any
+ * noticeable difference).
+ *
+ * Anyways, so, here's finally a working driver for inic162x.  Enjoy!
+ *
+ * initio: If you guys wanna improve the driver regarding result TF
+ * access and other stuff, please feel free to contact me.  I'll be
+ * happy to assist.
  */
 
 #include <linux/kernel.h>
@@ -28,13 +48,19 @@
 #include <scsi/scsi_device.h>
 
 #define DRV_NAME	"sata_inic162x"
-#define DRV_VERSION	"0.3"
+#define DRV_VERSION	"0.4"
 
 enum {
-	MMIO_BAR		= 5,
+	MMIO_BAR_PCI		= 5,
+	MMIO_BAR_CARDBUS	= 1,
 
 	NR_PORTS		= 2,
 
+	IDMA_CPB_TBL_SIZE	= 4 * 32,
+
+	INIC_DMA_BOUNDARY	= 0xffffff,
+
+	HOST_ACTRL		= 0x08,
 	HOST_CTL		= 0x7c,
 	HOST_STAT		= 0x7e,
 	HOST_IRQ_STAT		= 0xbc,
@@ -43,22 +69,37 @@
 	PORT_SIZE		= 0x40,
 
 	/* registers for ATA TF operation */
-	PORT_TF			= 0x00,
-	PORT_ALT_STAT		= 0x08,
+	PORT_TF_DATA		= 0x00,
+	PORT_TF_FEATURE		= 0x01,
+	PORT_TF_NSECT		= 0x02,
+	PORT_TF_LBAL		= 0x03,
+	PORT_TF_LBAM		= 0x04,
+	PORT_TF_LBAH		= 0x05,
+	PORT_TF_DEVICE		= 0x06,
+	PORT_TF_COMMAND		= 0x07,
+	PORT_TF_ALT_STAT	= 0x08,
 	PORT_IRQ_STAT		= 0x09,
 	PORT_IRQ_MASK		= 0x0a,
 	PORT_PRD_CTL		= 0x0b,
 	PORT_PRD_ADDR		= 0x0c,
 	PORT_PRD_XFERLEN	= 0x10,
+	PORT_CPB_CPBLAR		= 0x18,
+	PORT_CPB_PTQFIFO	= 0x1c,
 
 	/* IDMA register */
 	PORT_IDMA_CTL		= 0x14,
+	PORT_IDMA_STAT		= 0x16,
+
+	PORT_RPQ_FIFO		= 0x1e,
+	PORT_RPQ_CNT		= 0x1f,
 
 	PORT_SCR		= 0x20,
 
 	/* HOST_CTL bits */
 	HCTL_IRQOFF		= (1 << 8),  /* global IRQ off */
-	HCTL_PWRDWN		= (1 << 13), /* power down PHYs */
+	HCTL_FTHD0		= (1 << 10), /* fifo threshold 0 */
+	HCTL_FTHD1		= (1 << 11), /* fifo threshold 1*/
+	HCTL_PWRDWN		= (1 << 12), /* power down PHYs */
 	HCTL_SOFTRST		= (1 << 13), /* global reset (no phy reset) */
 	HCTL_RPGSEL		= (1 << 15), /* register page select */
 
@@ -81,9 +122,7 @@
 	PIRQ_PENDING		= (1 << 7),  /* port IRQ pending (STAT only) */
 
 	PIRQ_ERR		= PIRQ_OFFLINE | PIRQ_ONLINE | PIRQ_FATAL,
-
-	PIRQ_MASK_DMA_READ	= PIRQ_REPLY | PIRQ_ATA,
-	PIRQ_MASK_OTHER		= PIRQ_REPLY | PIRQ_COMPLETE,
+	PIRQ_MASK_DEFAULT	= PIRQ_REPLY | PIRQ_ATA,
 	PIRQ_MASK_FREEZE	= 0xff,
 
 	/* PORT_PRD_CTL bits */
@@ -96,20 +135,104 @@
 	IDMA_CTL_RST_IDMA	= (1 << 5),  /* reset IDMA machinary */
 	IDMA_CTL_GO		= (1 << 7),  /* IDMA mode go */
 	IDMA_CTL_ATA_NIEN	= (1 << 8),  /* ATA IRQ disable */
+
+	/* PORT_IDMA_STAT bits */
+	IDMA_STAT_PERR		= (1 << 0),  /* PCI ERROR MODE */
+	IDMA_STAT_CPBERR	= (1 << 1),  /* ADMA CPB error */
+	IDMA_STAT_LGCY		= (1 << 3),  /* ADMA legacy */
+	IDMA_STAT_UIRQ		= (1 << 4),  /* ADMA unsolicited irq */
+	IDMA_STAT_STPD		= (1 << 5),  /* ADMA stopped */
+	IDMA_STAT_PSD		= (1 << 6),  /* ADMA pause */
+	IDMA_STAT_DONE		= (1 << 7),  /* ADMA done */
+
+	IDMA_STAT_ERR		= IDMA_STAT_PERR | IDMA_STAT_CPBERR,
+
+	/* CPB Control Flags*/
+	CPB_CTL_VALID		= (1 << 0),  /* CPB valid */
+	CPB_CTL_QUEUED		= (1 << 1),  /* queued command */
+	CPB_CTL_DATA		= (1 << 2),  /* data, rsvd in datasheet */
+	CPB_CTL_IEN		= (1 << 3),  /* PCI interrupt enable */
+	CPB_CTL_DEVDIR		= (1 << 4),  /* device direction control */
+
+	/* CPB Response Flags */
+	CPB_RESP_DONE		= (1 << 0),  /* ATA command complete */
+	CPB_RESP_REL		= (1 << 1),  /* ATA release */
+	CPB_RESP_IGNORED	= (1 << 2),  /* CPB ignored */
+	CPB_RESP_ATA_ERR	= (1 << 3),  /* ATA command error */
+	CPB_RESP_SPURIOUS	= (1 << 4),  /* ATA spurious interrupt error */
+	CPB_RESP_UNDERFLOW	= (1 << 5),  /* APRD deficiency length error */
+	CPB_RESP_OVERFLOW	= (1 << 6),  /* APRD exccess length error */
+	CPB_RESP_CPB_ERR	= (1 << 7),  /* CPB error flag */
+
+	/* PRD Control Flags */
+	PRD_DRAIN		= (1 << 1),  /* ignore data excess */
+	PRD_CDB			= (1 << 2),  /* atapi packet command pointer */
+	PRD_DIRECT_INTR		= (1 << 3),  /* direct interrupt */
+	PRD_DMA			= (1 << 4),  /* data transfer method */
+	PRD_WRITE		= (1 << 5),  /* data dir, rsvd in datasheet */
+	PRD_IOM			= (1 << 6),  /* io/memory transfer */
+	PRD_END			= (1 << 7),  /* APRD chain end */
 };
 
+/* Comman Parameter Block */
+struct inic_cpb {
+	u8		resp_flags;	/* Response Flags */
+	u8		error;		/* ATA Error */
+	u8		status;		/* ATA Status */
+	u8		ctl_flags;	/* Control Flags */
+	__le32		len;		/* Total Transfer Length */
+	__le32		prd;		/* First PRD pointer */
+	u8		rsvd[4];
+	/* 16 bytes */
+	u8		feature;	/* ATA Feature */
+	u8		hob_feature;	/* ATA Ex. Feature */
+	u8		device;		/* ATA Device/Head */
+	u8		mirctl;		/* Mirror Control */
+	u8		nsect;		/* ATA Sector Count */
+	u8		hob_nsect;	/* ATA Ex. Sector Count */
+	u8		lbal;		/* ATA Sector Number */
+	u8		hob_lbal;	/* ATA Ex. Sector Number */
+	u8		lbam;		/* ATA Cylinder Low */
+	u8		hob_lbam;	/* ATA Ex. Cylinder Low */
+	u8		lbah;		/* ATA Cylinder High */
+	u8		hob_lbah;	/* ATA Ex. Cylinder High */
+	u8		command;	/* ATA Command */
+	u8		ctl;		/* ATA Control */
+	u8		slave_error;	/* Slave ATA Error */
+	u8		slave_status;	/* Slave ATA Status */
+	/* 32 bytes */
+} __packed;
+
+/* Physical Region Descriptor */
+struct inic_prd {
+	__le32		mad;		/* Physical Memory Address */
+	__le16		len;		/* Transfer Length */
+	u8		rsvd;
+	u8		flags;		/* Control Flags */
+} __packed;
+
+struct inic_pkt {
+	struct inic_cpb	cpb;
+	struct inic_prd	prd[LIBATA_MAX_PRD + 1];	/* + 1 for cdb */
+	u8		cdb[ATAPI_CDB_LEN];
+} __packed;
+
 struct inic_host_priv {
-	u16	cached_hctl;
+	void __iomem	*mmio_base;
+	u16		cached_hctl;
 };
 
 struct inic_port_priv {
-	u8	dfl_prdctl;
-	u8	cached_prdctl;
-	u8	cached_pirq_mask;
+	struct inic_pkt	*pkt;
+	dma_addr_t	pkt_dma;
+	u32		*cpb_tbl;
+	dma_addr_t	cpb_tbl_dma;
 };
 
 static struct scsi_host_template inic_sht = {
-	ATA_BMDMA_SHT(DRV_NAME),
+	ATA_BASE_SHT(DRV_NAME),
+	.sg_tablesize	= LIBATA_MAX_PRD,	/* maybe it can be larger? */
+	.dma_boundary	= INIC_DMA_BOUNDARY,
 };
 
 static const int scr_map[] = {
@@ -120,54 +243,34 @@
 
 static void __iomem *inic_port_base(struct ata_port *ap)
 {
-	return ap->host->iomap[MMIO_BAR] + ap->port_no * PORT_SIZE;
-}
+	struct inic_host_priv *hpriv = ap->host->private_data;
 
-static void __inic_set_pirq_mask(struct ata_port *ap, u8 mask)
-{
-	void __iomem *port_base = inic_port_base(ap);
-	struct inic_port_priv *pp = ap->private_data;
-
-	writeb(mask, port_base + PORT_IRQ_MASK);
-	pp->cached_pirq_mask = mask;
-}
-
-static void inic_set_pirq_mask(struct ata_port *ap, u8 mask)
-{
-	struct inic_port_priv *pp = ap->private_data;
-
-	if (pp->cached_pirq_mask != mask)
-		__inic_set_pirq_mask(ap, mask);
+	return hpriv->mmio_base + ap->port_no * PORT_SIZE;
 }
 
 static void inic_reset_port(void __iomem *port_base)
 {
 	void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
-	u16 ctl;
 
-	ctl = readw(idma_ctl);
-	ctl &= ~(IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN | IDMA_CTL_GO);
+	/* stop IDMA engine */
+	readw(idma_ctl); /* flush */
+	msleep(1);
 
 	/* mask IRQ and assert reset */
-	writew(ctl | IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN, idma_ctl);
+	writew(IDMA_CTL_RST_IDMA, idma_ctl);
 	readw(idma_ctl); /* flush */
-
-	/* give it some time */
 	msleep(1);
 
 	/* release reset */
-	writew(ctl | IDMA_CTL_ATA_NIEN, idma_ctl);
+	writew(0, idma_ctl);
 
 	/* clear irq */
 	writeb(0xff, port_base + PORT_IRQ_STAT);
-
-	/* reenable ATA IRQ, turn off IDMA mode */
-	writew(ctl, idma_ctl);
 }
 
 static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
 {
-	void __iomem *scr_addr = ap->ioaddr.scr_addr;
+	void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
 	void __iomem *addr;
 
 	if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
@@ -184,120 +287,126 @@
 
 static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
 {
-	void __iomem *scr_addr = ap->ioaddr.scr_addr;
-	void __iomem *addr;
+	void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
 
 	if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
 		return -EINVAL;
 
-	addr = scr_addr + scr_map[sc_reg] * 4;
 	writel(val, scr_addr + scr_map[sc_reg] * 4);
 	return 0;
 }
 
-/*
- * In TF mode, inic162x is very similar to SFF device.  TF registers
- * function the same.  DMA engine behaves similary using the same PRD
- * format as BMDMA but different command register, interrupt and event
- * notification methods are used.  The following inic_bmdma_*()
- * functions do the impedance matching.
- */
-static void inic_bmdma_setup(struct ata_queued_cmd *qc)
+static void inic_stop_idma(struct ata_port *ap)
 {
-	struct ata_port *ap = qc->ap;
-	struct inic_port_priv *pp = ap->private_data;
-	void __iomem *port_base = inic_port_base(ap);
-	int rw = qc->tf.flags & ATA_TFLAG_WRITE;
-
-	/* make sure device sees PRD table writes */
-	wmb();
-
-	/* load transfer length */
-	writel(qc->nbytes, port_base + PORT_PRD_XFERLEN);
-
-	/* turn on DMA and specify data direction */
-	pp->cached_prdctl = pp->dfl_prdctl | PRD_CTL_DMAEN;
-	if (!rw)
-		pp->cached_prdctl |= PRD_CTL_WR;
-	writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
-
-	/* issue r/w command */
-	ap->ops->sff_exec_command(ap, &qc->tf);
-}
-
-static void inic_bmdma_start(struct ata_queued_cmd *qc)
-{
-	struct ata_port *ap = qc->ap;
-	struct inic_port_priv *pp = ap->private_data;
 	void __iomem *port_base = inic_port_base(ap);
 
-	/* start host DMA transaction */
-	pp->cached_prdctl |= PRD_CTL_START;
-	writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
+	readb(port_base + PORT_RPQ_FIFO);
+	readb(port_base + PORT_RPQ_CNT);
+	writew(0, port_base + PORT_IDMA_CTL);
 }
 
-static void inic_bmdma_stop(struct ata_queued_cmd *qc)
+static void inic_host_err_intr(struct ata_port *ap, u8 irq_stat, u16 idma_stat)
 {
-	struct ata_port *ap = qc->ap;
+	struct ata_eh_info *ehi = &ap->link.eh_info;
 	struct inic_port_priv *pp = ap->private_data;
-	void __iomem *port_base = inic_port_base(ap);
+	struct inic_cpb *cpb = &pp->pkt->cpb;
+	bool freeze = false;
 
-	/* stop DMA engine */
-	writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
-}
+	ata_ehi_clear_desc(ehi);
+	ata_ehi_push_desc(ehi, "irq_stat=0x%x idma_stat=0x%x",
+			  irq_stat, idma_stat);
 
-static u8 inic_bmdma_status(struct ata_port *ap)
-{
-	/* event is already verified by the interrupt handler */
-	return ATA_DMA_INTR;
+	inic_stop_idma(ap);
+
+	if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) {
+		ata_ehi_push_desc(ehi, "hotplug");
+		ata_ehi_hotplugged(ehi);
+		freeze = true;
+	}
+
+	if (idma_stat & IDMA_STAT_PERR) {
+		ata_ehi_push_desc(ehi, "PCI error");
+		freeze = true;
+	}
+
+	if (idma_stat & IDMA_STAT_CPBERR) {
+		ata_ehi_push_desc(ehi, "CPB error");
+
+		if (cpb->resp_flags & CPB_RESP_IGNORED) {
+			__ata_ehi_push_desc(ehi, " ignored");
+			ehi->err_mask |= AC_ERR_INVALID;
+			freeze = true;
+		}
+
+		if (cpb->resp_flags & CPB_RESP_ATA_ERR)
+			ehi->err_mask |= AC_ERR_DEV;
+
+		if (cpb->resp_flags & CPB_RESP_SPURIOUS) {
+			__ata_ehi_push_desc(ehi, " spurious-intr");
+			ehi->err_mask |= AC_ERR_HSM;
+			freeze = true;
+		}
+
+		if (cpb->resp_flags &
+		    (CPB_RESP_UNDERFLOW | CPB_RESP_OVERFLOW)) {
+			__ata_ehi_push_desc(ehi, " data-over/underflow");
+			ehi->err_mask |= AC_ERR_HSM;
+			freeze = true;
+		}
+	}
+
+	if (freeze)
+		ata_port_freeze(ap);
+	else
+		ata_port_abort(ap);
 }
 
 static void inic_host_intr(struct ata_port *ap)
 {
 	void __iomem *port_base = inic_port_base(ap);
-	struct ata_eh_info *ehi = &ap->link.eh_info;
+	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
 	u8 irq_stat;
+	u16 idma_stat;
 
-	/* fetch and clear irq */
+	/* read and clear IRQ status */
 	irq_stat = readb(port_base + PORT_IRQ_STAT);
 	writeb(irq_stat, port_base + PORT_IRQ_STAT);
+	idma_stat = readw(port_base + PORT_IDMA_STAT);
 
-	if (likely(!(irq_stat & PIRQ_ERR))) {
-		struct ata_queued_cmd *qc =
-			ata_qc_from_tag(ap, ap->link.active_tag);
+	if (unlikely((irq_stat & PIRQ_ERR) || (idma_stat & IDMA_STAT_ERR)))
+		inic_host_err_intr(ap, irq_stat, idma_stat);
 
-		if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
-			ap->ops->sff_check_status(ap); /* clear ATA interrupt */
-			return;
-		}
+	if (unlikely(!qc))
+		goto spurious;
 
-		if (likely(ata_sff_host_intr(ap, qc)))
-			return;
+	if (likely(idma_stat & IDMA_STAT_DONE)) {
+		inic_stop_idma(ap);
 
-		ap->ops->sff_check_status(ap); /* clear ATA interrupt */
-		ata_port_printk(ap, KERN_WARNING, "unhandled "
-				"interrupt, irq_stat=%x\n", irq_stat);
+		/* Depending on circumstances, device error
+		 * isn't reported by IDMA, check it explicitly.
+		 */
+		if (unlikely(readb(port_base + PORT_TF_COMMAND) &
+			     (ATA_DF | ATA_ERR)))
+			qc->err_mask |= AC_ERR_DEV;
+
+		ata_qc_complete(qc);
 		return;
 	}
 
-	/* error */
-	ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat);
-
-	if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) {
-		ata_ehi_hotplugged(ehi);
-		ata_port_freeze(ap);
-	} else
-		ata_port_abort(ap);
+ spurious:
+	ata_port_printk(ap, KERN_WARNING, "unhandled interrupt: "
+			"cmd=0x%x irq_stat=0x%x idma_stat=0x%x\n",
+			qc ? qc->tf.command : 0xff, irq_stat, idma_stat);
 }
 
 static irqreturn_t inic_interrupt(int irq, void *dev_instance)
 {
 	struct ata_host *host = dev_instance;
-	void __iomem *mmio_base = host->iomap[MMIO_BAR];
+	struct inic_host_priv *hpriv = host->private_data;
 	u16 host_irq_stat;
 	int i, handled = 0;;
 
-	host_irq_stat = readw(mmio_base + HOST_IRQ_STAT);
+	host_irq_stat = readw(hpriv->mmio_base + HOST_IRQ_STAT);
 
 	if (unlikely(!(host_irq_stat & HIRQ_GLOBAL)))
 		goto out;
@@ -327,60 +436,173 @@
 	return IRQ_RETVAL(handled);
 }
 
+static int inic_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	/* For some reason ATAPI_PROT_DMA doesn't work for some
+	 * commands including writes and other misc ops.  Use PIO
+	 * protocol instead, which BTW is driven by the DMA engine
+	 * anyway, so it shouldn't make much difference for native
+	 * SATA devices.
+	 */
+	if (atapi_cmd_type(qc->cdb[0]) == READ)
+		return 0;
+	return 1;
+}
+
+static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc)
+{
+	struct scatterlist *sg;
+	unsigned int si;
+	u8 flags = 0;
+
+	if (qc->tf.flags & ATA_TFLAG_WRITE)
+		flags |= PRD_WRITE;
+
+	if (ata_is_dma(qc->tf.protocol))
+		flags |= PRD_DMA;
+
+	for_each_sg(qc->sg, sg, qc->n_elem, si) {
+		prd->mad = cpu_to_le32(sg_dma_address(sg));
+		prd->len = cpu_to_le16(sg_dma_len(sg));
+		prd->flags = flags;
+		prd++;
+	}
+
+	WARN_ON(!si);
+	prd[-1].flags |= PRD_END;
+}
+
+static void inic_qc_prep(struct ata_queued_cmd *qc)
+{
+	struct inic_port_priv *pp = qc->ap->private_data;
+	struct inic_pkt *pkt = pp->pkt;
+	struct inic_cpb *cpb = &pkt->cpb;
+	struct inic_prd *prd = pkt->prd;
+	bool is_atapi = ata_is_atapi(qc->tf.protocol);
+	bool is_data = ata_is_data(qc->tf.protocol);
+	unsigned int cdb_len = 0;
+
+	VPRINTK("ENTER\n");
+
+	if (is_atapi)
+		cdb_len = qc->dev->cdb_len;
+
+	/* prepare packet, based on initio driver */
+	memset(pkt, 0, sizeof(struct inic_pkt));
+
+	cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN;
+	if (is_atapi || is_data)
+		cpb->ctl_flags |= CPB_CTL_DATA;
+
+	cpb->len = cpu_to_le32(qc->nbytes + cdb_len);
+	cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd));
+
+	cpb->device = qc->tf.device;
+	cpb->feature = qc->tf.feature;
+	cpb->nsect = qc->tf.nsect;
+	cpb->lbal = qc->tf.lbal;
+	cpb->lbam = qc->tf.lbam;
+	cpb->lbah = qc->tf.lbah;
+
+	if (qc->tf.flags & ATA_TFLAG_LBA48) {
+		cpb->hob_feature = qc->tf.hob_feature;
+		cpb->hob_nsect = qc->tf.hob_nsect;
+		cpb->hob_lbal = qc->tf.hob_lbal;
+		cpb->hob_lbam = qc->tf.hob_lbam;
+		cpb->hob_lbah = qc->tf.hob_lbah;
+	}
+
+	cpb->command = qc->tf.command;
+	/* don't load ctl - dunno why.  it's like that in the initio driver */
+
+	/* setup PRD for CDB */
+	if (is_atapi) {
+		memcpy(pkt->cdb, qc->cdb, ATAPI_CDB_LEN);
+		prd->mad = cpu_to_le32(pp->pkt_dma +
+				       offsetof(struct inic_pkt, cdb));
+		prd->len = cpu_to_le16(cdb_len);
+		prd->flags = PRD_CDB | PRD_WRITE;
+		if (!is_data)
+			prd->flags |= PRD_END;
+		prd++;
+	}
+
+	/* setup sg table */
+	if (is_data)
+		inic_fill_sg(prd, qc);
+
+	pp->cpb_tbl[0] = pp->pkt_dma;
+}
+
 static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
+	void __iomem *port_base = inic_port_base(ap);
 
-	/* ATA IRQ doesn't wait for DMA transfer completion and vice
-	 * versa.  Mask IRQ selectively to detect command completion.
-	 * Without it, ATA DMA read command can cause data corruption.
-	 *
-	 * Something similar might be needed for ATAPI writes.  I
-	 * tried a lot of combinations but couldn't find the solution.
+	/* fire up the ADMA engine */
+	writew(HCTL_FTHD0, port_base + HOST_CTL);
+	writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL);
+	writeb(0, port_base + PORT_CPB_PTQFIFO);
+
+	return 0;
+}
+
+static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	void __iomem *port_base = inic_port_base(ap);
+
+	tf->feature	= readb(port_base + PORT_TF_FEATURE);
+	tf->nsect	= readb(port_base + PORT_TF_NSECT);
+	tf->lbal	= readb(port_base + PORT_TF_LBAL);
+	tf->lbam	= readb(port_base + PORT_TF_LBAM);
+	tf->lbah	= readb(port_base + PORT_TF_LBAH);
+	tf->device	= readb(port_base + PORT_TF_DEVICE);
+	tf->command	= readb(port_base + PORT_TF_COMMAND);
+}
+
+static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+	struct ata_taskfile *rtf = &qc->result_tf;
+	struct ata_taskfile tf;
+
+	/* FIXME: Except for status and error, result TF access
+	 * doesn't work.  I tried reading from BAR0/2, CPB and BAR5.
+	 * None works regardless of which command interface is used.
+	 * For now return true iff status indicates device error.
+	 * This means that we're reporting bogus sector for RW
+	 * failures.  Eeekk....
 	 */
-	if (qc->tf.protocol == ATA_PROT_DMA &&
-	    !(qc->tf.flags & ATA_TFLAG_WRITE))
-		inic_set_pirq_mask(ap, PIRQ_MASK_DMA_READ);
-	else
-		inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+	inic_tf_read(qc->ap, &tf);
 
-	/* Issuing a command to yet uninitialized port locks up the
-	 * controller.  Most of the time, this happens for the first
-	 * command after reset which are ATA and ATAPI IDENTIFYs.
-	 * Fast fail if stat is 0x7f or 0xff for those commands.
-	 */
-	if (unlikely(qc->tf.command == ATA_CMD_ID_ATA ||
-		     qc->tf.command == ATA_CMD_ID_ATAPI)) {
-		u8 stat = ap->ops->sff_check_status(ap);
-		if (stat == 0x7f || stat == 0xff)
-			return AC_ERR_HSM;
-	}
+	if (!(tf.command & ATA_ERR))
+		return false;
 
-	return ata_sff_qc_issue(qc);
+	rtf->command = tf.command;
+	rtf->feature = tf.feature;
+	return true;
 }
 
 static void inic_freeze(struct ata_port *ap)
 {
 	void __iomem *port_base = inic_port_base(ap);
 
-	__inic_set_pirq_mask(ap, PIRQ_MASK_FREEZE);
-
-	ap->ops->sff_check_status(ap);
+	writeb(PIRQ_MASK_FREEZE, port_base + PORT_IRQ_MASK);
 	writeb(0xff, port_base + PORT_IRQ_STAT);
-
-	readb(port_base + PORT_IRQ_STAT); /* flush */
 }
 
 static void inic_thaw(struct ata_port *ap)
 {
 	void __iomem *port_base = inic_port_base(ap);
 
-	ap->ops->sff_check_status(ap);
 	writeb(0xff, port_base + PORT_IRQ_STAT);
+	writeb(PIRQ_MASK_DEFAULT, port_base + PORT_IRQ_MASK);
+}
 
-	__inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+static int inic_check_ready(struct ata_link *link)
+{
+	void __iomem *port_base = inic_port_base(link->ap);
 
-	readb(port_base + PORT_IRQ_STAT); /* flush */
+	return ata_check_ready(readb(port_base + PORT_TF_COMMAND));
 }
 
 /*
@@ -394,17 +616,15 @@
 	void __iomem *port_base = inic_port_base(ap);
 	void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
 	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
-	u16 val;
 	int rc;
 
 	/* hammer it into sane state */
 	inic_reset_port(port_base);
 
-	val = readw(idma_ctl);
-	writew(val | IDMA_CTL_RST_ATA, idma_ctl);
+	writew(IDMA_CTL_RST_ATA, idma_ctl);
 	readw(idma_ctl);	/* flush */
 	msleep(1);
-	writew(val & ~IDMA_CTL_RST_ATA, idma_ctl);
+	writew(0, idma_ctl);
 
 	rc = sata_link_resume(link, timing, deadline);
 	if (rc) {
@@ -418,7 +638,7 @@
 		struct ata_taskfile tf;
 
 		/* wait for link to become ready */
-		rc = ata_sff_wait_after_reset(link, 1, deadline);
+		rc = ata_wait_after_reset(link, deadline, inic_check_ready);
 		/* link occupied, -ENODEV too is an error */
 		if (rc) {
 			ata_link_printk(link, KERN_WARNING, "device not ready "
@@ -426,7 +646,7 @@
 			return rc;
 		}
 
-		ata_sff_tf_read(ap, &tf);
+		inic_tf_read(ap, &tf);
 		*class = ata_dev_classify(&tf);
 	}
 
@@ -436,18 +656,8 @@
 static void inic_error_handler(struct ata_port *ap)
 {
 	void __iomem *port_base = inic_port_base(ap);
-	struct inic_port_priv *pp = ap->private_data;
-	unsigned long flags;
 
-	/* reset PIO HSM and stop DMA engine */
 	inic_reset_port(port_base);
-
-	spin_lock_irqsave(ap->lock, flags);
-	ap->hsm_task_state = HSM_ST_IDLE;
-	writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
-	spin_unlock_irqrestore(ap->lock, flags);
-
-	/* PIO and DMA engines have been stopped, perform recovery */
 	ata_std_error_handler(ap);
 }
 
@@ -458,26 +668,18 @@
 		inic_reset_port(inic_port_base(qc->ap));
 }
 
-static void inic_dev_config(struct ata_device *dev)
-{
-	/* inic can only handle upto LBA28 max sectors */
-	if (dev->max_sectors > ATA_MAX_SECTORS)
-		dev->max_sectors = ATA_MAX_SECTORS;
-
-	if (dev->n_sectors >= 1 << 28) {
-		ata_dev_printk(dev, KERN_ERR,
-	"ERROR: This driver doesn't support LBA48 yet and may cause\n"
-	"                data corruption on such devices.  Disabling.\n");
-		ata_dev_disable(dev);
-	}
-}
-
 static void init_port(struct ata_port *ap)
 {
 	void __iomem *port_base = inic_port_base(ap);
+	struct inic_port_priv *pp = ap->private_data;
 
-	/* Setup PRD address */
+	/* clear packet and CPB table */
+	memset(pp->pkt, 0, sizeof(struct inic_pkt));
+	memset(pp->cpb_tbl, 0, IDMA_CPB_TBL_SIZE);
+
+	/* setup PRD and CPB lookup table addresses */
 	writel(ap->prd_dma, port_base + PORT_PRD_ADDR);
+	writel(pp->cpb_tbl_dma, port_base + PORT_CPB_CPBLAR);
 }
 
 static int inic_port_resume(struct ata_port *ap)
@@ -488,28 +690,30 @@
 
 static int inic_port_start(struct ata_port *ap)
 {
-	void __iomem *port_base = inic_port_base(ap);
+	struct device *dev = ap->host->dev;
 	struct inic_port_priv *pp;
-	u8 tmp;
 	int rc;
 
 	/* alloc and initialize private data */
-	pp = devm_kzalloc(ap->host->dev, sizeof(*pp), GFP_KERNEL);
+	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
 	if (!pp)
 		return -ENOMEM;
 	ap->private_data = pp;
 
-	/* default PRD_CTL value, DMAEN, WR and START off */
-	tmp = readb(port_base + PORT_PRD_CTL);
-	tmp &= ~(PRD_CTL_DMAEN | PRD_CTL_WR | PRD_CTL_START);
-	pp->dfl_prdctl = tmp;
-
 	/* Alloc resources */
 	rc = ata_port_start(ap);
-	if (rc) {
-		kfree(pp);
+	if (rc)
 		return rc;
-	}
+
+	pp->pkt = dmam_alloc_coherent(dev, sizeof(struct inic_pkt),
+				      &pp->pkt_dma, GFP_KERNEL);
+	if (!pp->pkt)
+		return -ENOMEM;
+
+	pp->cpb_tbl = dmam_alloc_coherent(dev, IDMA_CPB_TBL_SIZE,
+					  &pp->cpb_tbl_dma, GFP_KERNEL);
+	if (!pp->cpb_tbl)
+		return -ENOMEM;
 
 	init_port(ap);
 
@@ -517,21 +721,18 @@
 }
 
 static struct ata_port_operations inic_port_ops = {
-	.inherits		= &ata_sff_port_ops,
+	.inherits		= &sata_port_ops,
 
-	.bmdma_setup		= inic_bmdma_setup,
-	.bmdma_start		= inic_bmdma_start,
-	.bmdma_stop		= inic_bmdma_stop,
-	.bmdma_status		= inic_bmdma_status,
+	.check_atapi_dma	= inic_check_atapi_dma,
+	.qc_prep		= inic_qc_prep,
 	.qc_issue		= inic_qc_issue,
+	.qc_fill_rtf		= inic_qc_fill_rtf,
 
 	.freeze			= inic_freeze,
 	.thaw			= inic_thaw,
-	.softreset		= ATA_OP_NULL,	/* softreset is broken */
 	.hardreset		= inic_hardreset,
 	.error_handler		= inic_error_handler,
 	.post_internal_cmd	= inic_post_internal_cmd,
-	.dev_config		= inic_dev_config,
 
 	.scr_read		= inic_scr_read,
 	.scr_write		= inic_scr_write,
@@ -541,12 +742,6 @@
 };
 
 static struct ata_port_info inic_port_info = {
-	/* For some reason, ATAPI_PROT_PIO is broken on this
-	 * controller, and no, PIO_POLLING does't fix it.  It somehow
-	 * manages to report the wrong ireason and ignoring ireason
-	 * results in machine lock up.  Tell libata to always prefer
-	 * DMA.
-	 */
 	.flags			= ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
 	.pio_mask		= 0x1f,	/* pio0-4 */
 	.mwdma_mask		= 0x07, /* mwdma0-2 */
@@ -599,7 +794,6 @@
 {
 	struct ata_host *host = dev_get_drvdata(&pdev->dev);
 	struct inic_host_priv *hpriv = host->private_data;
-	void __iomem *mmio_base = host->iomap[MMIO_BAR];
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
@@ -607,7 +801,7 @@
 		return rc;
 
 	if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-		rc = init_controller(mmio_base, hpriv->cached_hctl);
+		rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
 		if (rc)
 			return rc;
 	}
@@ -625,6 +819,7 @@
 	struct ata_host *host;
 	struct inic_host_priv *hpriv;
 	void __iomem * const *iomap;
+	int mmio_bar;
 	int i, rc;
 
 	if (!printed_version++)
@@ -638,39 +833,32 @@
 
 	host->private_data = hpriv;
 
-	/* acquire resources and fill host */
+	/* Acquire resources and fill host.  Note that PCI and cardbus
+	 * use different BARs.
+	 */
 	rc = pcim_enable_device(pdev);
 	if (rc)
 		return rc;
 
-	rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
+	if (pci_resource_flags(pdev, MMIO_BAR_PCI) & IORESOURCE_MEM)
+		mmio_bar = MMIO_BAR_PCI;
+	else
+		mmio_bar = MMIO_BAR_CARDBUS;
+
+	rc = pcim_iomap_regions(pdev, 1 << mmio_bar, DRV_NAME);
 	if (rc)
 		return rc;
 	host->iomap = iomap = pcim_iomap_table(pdev);
+	hpriv->mmio_base = iomap[mmio_bar];
+	hpriv->cached_hctl = readw(hpriv->mmio_base + HOST_CTL);
 
 	for (i = 0; i < NR_PORTS; i++) {
 		struct ata_port *ap = host->ports[i];
-		struct ata_ioports *port = &ap->ioaddr;
-		unsigned int offset = i * PORT_SIZE;
 
-		port->cmd_addr = iomap[2 * i];
-		port->altstatus_addr =
-		port->ctl_addr = (void __iomem *)
-			((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
-		port->scr_addr = iomap[MMIO_BAR] + offset + PORT_SCR;
-
-		ata_sff_std_ports(port);
-
-		ata_port_pbar_desc(ap, MMIO_BAR, -1, "mmio");
-		ata_port_pbar_desc(ap, MMIO_BAR, offset, "port");
-		ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
-		  (unsigned long long)pci_resource_start(pdev, 2 * i),
-		  (unsigned long long)pci_resource_start(pdev, (2 * i + 1)) |
-				      ATA_PCI_CTL_OFS);
+		ata_port_pbar_desc(ap, mmio_bar, -1, "mmio");
+		ata_port_pbar_desc(ap, mmio_bar, i * PORT_SIZE, "port");
 	}
 
-	hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
-
 	/* Set dma_mask.  This devices doesn't support 64bit addressing. */
 	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 	if (rc) {
@@ -698,7 +886,7 @@
 		return rc;
 	}
 
-	rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl);
+	rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
 	if (rc) {
 		dev_printk(KERN_ERR, &pdev->dev,
 			   "failed to initialize controller\n");
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 842b1a15..bb73b22 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -65,6 +65,7 @@
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
+#include <linux/bitops.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -91,9 +92,9 @@
 	MV_IRQ_COAL_TIME_THRESHOLD	= (MV_IRQ_COAL_REG_BASE + 0xd0),
 
 	MV_SATAHC0_REG_BASE	= 0x20000,
-	MV_FLASH_CTL		= 0x1046c,
-	MV_GPIO_PORT_CTL	= 0x104f0,
-	MV_RESET_CFG		= 0x180d8,
+	MV_FLASH_CTL_OFS	= 0x1046c,
+	MV_GPIO_PORT_CTL_OFS	= 0x104f0,
+	MV_RESET_CFG_OFS	= 0x180d8,
 
 	MV_PCI_REG_SZ		= MV_MAJOR_REG_AREA_SZ,
 	MV_SATAHC_REG_SZ	= MV_MAJOR_REG_AREA_SZ,
@@ -147,18 +148,21 @@
 	/* PCI interface registers */
 
 	PCI_COMMAND_OFS		= 0xc00,
+	PCI_COMMAND_MRDTRIG	= (1 << 7),	/* PCI Master Read Trigger */
 
 	PCI_MAIN_CMD_STS_OFS	= 0xd30,
 	STOP_PCI_MASTER		= (1 << 2),
 	PCI_MASTER_EMPTY	= (1 << 3),
 	GLOB_SFT_RST		= (1 << 4),
 
-	MV_PCI_MODE		= 0xd00,
+	MV_PCI_MODE_OFS		= 0xd00,
+	MV_PCI_MODE_MASK	= 0x30,
+
 	MV_PCI_EXP_ROM_BAR_CTL	= 0xd2c,
 	MV_PCI_DISC_TIMER	= 0xd04,
 	MV_PCI_MSI_TRIGGER	= 0xc38,
 	MV_PCI_SERR_MASK	= 0xc28,
-	MV_PCI_XBAR_TMOUT	= 0x1d04,
+	MV_PCI_XBAR_TMOUT_OFS	= 0x1d04,
 	MV_PCI_ERR_LOW_ADDRESS	= 0x1d40,
 	MV_PCI_ERR_HIGH_ADDRESS	= 0x1d44,
 	MV_PCI_ERR_ATTRIBUTE	= 0x1d48,
@@ -225,16 +229,18 @@
 	PHY_MODE4		= 0x314,
 	PHY_MODE2		= 0x330,
 	SATA_IFCTL_OFS		= 0x344,
+	SATA_TESTCTL_OFS	= 0x348,
 	SATA_IFSTAT_OFS		= 0x34c,
 	VENDOR_UNIQUE_FIS_OFS	= 0x35c,
 
-	FIS_CFG_OFS		= 0x360,
-	FIS_CFG_SINGLE_SYNC	= (1 << 16),	/* SYNC on DMA activation */
+	FISCFG_OFS		= 0x360,
+	FISCFG_WAIT_DEV_ERR	= (1 << 8),	/* wait for host on DevErr */
+	FISCFG_SINGLE_SYNC	= (1 << 16),	/* SYNC on DMA activation */
 
 	MV5_PHY_MODE		= 0x74,
-	MV5_LT_MODE		= 0x30,
-	MV5_PHY_CTL		= 0x0C,
-	SATA_INTERFACE_CFG	= 0x050,
+	MV5_LTMODE_OFS		= 0x30,
+	MV5_PHY_CTL_OFS		= 0x0C,
+	SATA_INTERFACE_CFG_OFS	= 0x050,
 
 	MV_M2_PREAMP_MASK	= 0x7e0,
 
@@ -332,10 +338,16 @@
 	EDMA_CMD_OFS		= 0x28,		/* EDMA command register */
 	EDMA_EN			= (1 << 0),	/* enable EDMA */
 	EDMA_DS			= (1 << 1),	/* disable EDMA; self-negated */
-	ATA_RST			= (1 << 2),	/* reset trans/link/phy */
+	EDMA_RESET		= (1 << 2),	/* reset eng/trans/link/phy */
 
-	EDMA_IORDY_TMOUT	= 0x34,
-	EDMA_ARB_CFG		= 0x38,
+	EDMA_STATUS_OFS		= 0x30,		/* EDMA engine status */
+	EDMA_STATUS_CACHE_EMPTY	= (1 << 6),	/* GenIIe command cache empty */
+	EDMA_STATUS_IDLE	= (1 << 7),	/* GenIIe EDMA enabled/idle */
+
+	EDMA_IORDY_TMOUT_OFS	= 0x34,
+	EDMA_ARB_CFG_OFS	= 0x38,
+
+	EDMA_HALTCOND_OFS	= 0x60,		/* GenIIe halt conditions */
 
 	GEN_II_NCQ_MAX_SECTORS	= 256,		/* max sects/io on Gen2 w/NCQ */
 
@@ -350,15 +362,19 @@
 	MV_HP_GEN_II		= (1 << 7),	/* Generation II: 60xx */
 	MV_HP_GEN_IIE		= (1 << 8),	/* Generation IIE: 6042/7042 */
 	MV_HP_PCIE		= (1 << 9),	/* PCIe bus/regs: 7042 */
+	MV_HP_CUT_THROUGH	= (1 << 10),	/* can use EDMA cut-through */
 
 	/* Port private flags (pp_flags) */
 	MV_PP_FLAG_EDMA_EN	= (1 << 0),	/* is EDMA engine enabled? */
 	MV_PP_FLAG_NCQ_EN	= (1 << 1),	/* is EDMA set up for NCQ? */
+	MV_PP_FLAG_FBS_EN	= (1 << 2),	/* is EDMA set up for FBS? */
+	MV_PP_FLAG_DELAYED_EH	= (1 << 3),	/* delayed dev err handling */
 };
 
 #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
 #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II)
 #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
+#define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE)
 #define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC))
 
 #define WINDOW_CTRL(i)		(0x20030 + ((i) << 4))
@@ -433,6 +449,7 @@
 	unsigned int		resp_idx;
 
 	u32			pp_flags;
+	unsigned int		delayed_eh_pmp_map;
 };
 
 struct mv_port_signal {
@@ -479,6 +496,7 @@
 static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
 static int mv_port_start(struct ata_port *ap);
 static void mv_port_stop(struct ata_port *ap);
+static int mv_qc_defer(struct ata_queued_cmd *qc);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
 static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
@@ -527,6 +545,9 @@
 				unsigned long deadline);
 static int  mv_softreset(struct ata_link *link, unsigned int *class,
 				unsigned long deadline);
+static void mv_pmp_error_handler(struct ata_port *ap);
+static void mv_process_crpb_entries(struct ata_port *ap,
+					struct mv_port_priv *pp);
 
 /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
  * because we have to allow room for worst case splitting of
@@ -548,6 +569,7 @@
 static struct ata_port_operations mv5_ops = {
 	.inherits		= &ata_sff_port_ops,
 
+	.qc_defer		= mv_qc_defer,
 	.qc_prep		= mv_qc_prep,
 	.qc_issue		= mv_qc_issue,
 
@@ -566,7 +588,6 @@
 
 static struct ata_port_operations mv6_ops = {
 	.inherits		= &mv5_ops,
-	.qc_defer		= sata_pmp_qc_defer_cmd_switch,
 	.dev_config             = mv6_dev_config,
 	.scr_read		= mv_scr_read,
 	.scr_write		= mv_scr_write,
@@ -574,12 +595,11 @@
 	.pmp_hardreset		= mv_pmp_hardreset,
 	.pmp_softreset		= mv_softreset,
 	.softreset		= mv_softreset,
-	.error_handler		= sata_pmp_error_handler,
+	.error_handler		= mv_pmp_error_handler,
 };
 
 static struct ata_port_operations mv_iie_ops = {
 	.inherits		= &mv6_ops,
-	.qc_defer		= ata_std_qc_defer, /* FIS-based switching */
 	.dev_config		= ATA_OP_NULL,
 	.qc_prep		= mv_qc_prep_iie,
 };
@@ -875,6 +895,29 @@
 	}
 }
 
+static void mv_wait_for_edma_empty_idle(struct ata_port *ap)
+{
+	void __iomem *port_mmio = mv_ap_base(ap);
+	const u32 empty_idle = (EDMA_STATUS_CACHE_EMPTY | EDMA_STATUS_IDLE);
+	const int per_loop = 5, timeout = (15 * 1000 / per_loop);
+	int i;
+
+	/*
+	 * Wait for the EDMA engine to finish transactions in progress.
+	 * No idea what a good "timeout" value might be, but measurements
+	 * indicate that it often requires hundreds of microseconds
+	 * with two drives in-use.  So we use the 15msec value above
+	 * as a rough guess at what even more drives might require.
+	 */
+	for (i = 0; i < timeout; ++i) {
+		u32 edma_stat = readl(port_mmio + EDMA_STATUS_OFS);
+		if ((edma_stat & empty_idle) == empty_idle)
+			break;
+		udelay(per_loop);
+	}
+	/* ata_port_printk(ap, KERN_INFO, "%s: %u+ usecs\n", __func__, i); */
+}
+
 /**
  *      mv_stop_edma_engine - Disable eDMA engine
  *      @port_mmio: io base address
@@ -907,6 +950,7 @@
 	if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
 		return 0;
 	pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+	mv_wait_for_edma_empty_idle(ap);
 	if (mv_stop_edma_engine(port_mmio)) {
 		ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
 		return -EIO;
@@ -1057,26 +1101,95 @@
 	}
 }
 
-static void mv_config_fbs(void __iomem *port_mmio, int enable_fbs)
+static int mv_qc_defer(struct ata_queued_cmd *qc)
 {
-	u32 old_fcfg, new_fcfg, old_ltmode, new_ltmode;
+	struct ata_link *link = qc->dev->link;
+	struct ata_port *ap = link->ap;
+	struct mv_port_priv *pp = ap->private_data;
+
 	/*
-	 * Various bit settings required for operation
-	 * in FIS-based switching (fbs) mode on GenIIe:
+	 * Don't allow new commands if we're in a delayed EH state
+	 * for NCQ and/or FIS-based switching.
 	 */
-	old_fcfg   = readl(port_mmio + FIS_CFG_OFS);
-	old_ltmode = readl(port_mmio + LTMODE_OFS);
-	if (enable_fbs) {
-		new_fcfg   = old_fcfg   |  FIS_CFG_SINGLE_SYNC;
-		new_ltmode = old_ltmode |  LTMODE_BIT8;
-	} else { /* disable fbs */
-		new_fcfg   = old_fcfg   & ~FIS_CFG_SINGLE_SYNC;
-		new_ltmode = old_ltmode & ~LTMODE_BIT8;
+	if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
+		return ATA_DEFER_PORT;
+	/*
+	 * If the port is completely idle, then allow the new qc.
+	 */
+	if (ap->nr_active_links == 0)
+		return 0;
+
+	if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
+		/*
+		 * The port is operating in host queuing mode (EDMA).
+		 * It can accomodate a new qc if the qc protocol
+		 * is compatible with the current host queue mode.
+		 */
+		if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
+			/*
+			 * The host queue (EDMA) is in NCQ mode.
+			 * If the new qc is also an NCQ command,
+			 * then allow the new qc.
+			 */
+			if (qc->tf.protocol == ATA_PROT_NCQ)
+				return 0;
+		} else {
+			/*
+			 * The host queue (EDMA) is in non-NCQ, DMA mode.
+			 * If the new qc is also a non-NCQ, DMA command,
+			 * then allow the new qc.
+			 */
+			if (qc->tf.protocol == ATA_PROT_DMA)
+				return 0;
+		}
 	}
-	if (new_fcfg != old_fcfg)
-		writelfl(new_fcfg, port_mmio + FIS_CFG_OFS);
+	return ATA_DEFER_PORT;
+}
+
+static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs)
+{
+	u32 new_fiscfg, old_fiscfg;
+	u32 new_ltmode, old_ltmode;
+	u32 new_haltcond, old_haltcond;
+
+	old_fiscfg   = readl(port_mmio + FISCFG_OFS);
+	old_ltmode   = readl(port_mmio + LTMODE_OFS);
+	old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+
+	new_fiscfg   = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
+	new_ltmode   = old_ltmode & ~LTMODE_BIT8;
+	new_haltcond = old_haltcond | EDMA_ERR_DEV;
+
+	if (want_fbs) {
+		new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC;
+		new_ltmode = old_ltmode | LTMODE_BIT8;
+		if (want_ncq)
+			new_haltcond &= ~EDMA_ERR_DEV;
+		else
+			new_fiscfg |=  FISCFG_WAIT_DEV_ERR;
+	}
+
+	if (new_fiscfg != old_fiscfg)
+		writelfl(new_fiscfg, port_mmio + FISCFG_OFS);
 	if (new_ltmode != old_ltmode)
 		writelfl(new_ltmode, port_mmio + LTMODE_OFS);
+	if (new_haltcond != old_haltcond)
+		writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS);
+}
+
+static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
+{
+	struct mv_host_priv *hpriv = ap->host->private_data;
+	u32 old, new;
+
+	/* workaround for 88SX60x1 FEr SATA#25 (part 1) */
+	old = readl(hpriv->base + MV_GPIO_PORT_CTL_OFS);
+	if (want_ncq)
+		new = old | (1 << 22);
+	else
+		new = old & ~(1 << 22);
+	if (new != old)
+		writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
 }
 
 static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
@@ -1088,25 +1201,40 @@
 
 	/* set up non-NCQ EDMA configuration */
 	cfg = EDMA_CFG_Q_DEPTH;		/* always 0x1f for *all* chips */
+	pp->pp_flags &= ~MV_PP_FLAG_FBS_EN;
 
 	if (IS_GEN_I(hpriv))
 		cfg |= (1 << 8);	/* enab config burst size mask */
 
-	else if (IS_GEN_II(hpriv))
+	else if (IS_GEN_II(hpriv)) {
 		cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN;
+		mv_60x1_errata_sata25(ap, want_ncq);
 
-	else if (IS_GEN_IIE(hpriv)) {
+	} else if (IS_GEN_IIE(hpriv)) {
+		int want_fbs = sata_pmp_attached(ap);
+		/*
+		 * Possible future enhancement:
+		 *
+		 * The chip can use FBS with non-NCQ, if we allow it,
+		 * But first we need to have the error handling in place
+		 * for this mode (datasheet section 7.3.15.4.2.3).
+		 * So disallow non-NCQ FBS for now.
+		 */
+		want_fbs &= want_ncq;
+
+		mv_config_fbs(port_mmio, want_ncq, want_fbs);
+
+		if (want_fbs) {
+			pp->pp_flags |= MV_PP_FLAG_FBS_EN;
+			cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */
+		}
+
 		cfg |= (1 << 23);	/* do not mask PM field in rx'd FIS */
 		cfg |= (1 << 22);	/* enab 4-entry host queue cache */
-		cfg |= (1 << 18);	/* enab early completion */
-		cfg |= (1 << 17);	/* enab cut-through (dis stor&forwrd) */
-
-		if (want_ncq && sata_pmp_attached(ap)) {
-			cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */
-			mv_config_fbs(port_mmio, 1);
-		} else {
-			mv_config_fbs(port_mmio, 0);
-		}
+		if (HAS_PCI(ap->host))
+			cfg |= (1 << 18);	/* enab early completion */
+		if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
+			cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
 	}
 
 	if (want_ncq) {
@@ -1483,25 +1611,186 @@
 	return qc;
 }
 
-static void mv_unexpected_intr(struct ata_port *ap)
+static void mv_pmp_error_handler(struct ata_port *ap)
 {
+	unsigned int pmp, pmp_map;
 	struct mv_port_priv *pp = ap->private_data;
-	struct ata_eh_info *ehi = &ap->link.eh_info;
-	char *when = "";
+
+	if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) {
+		/*
+		 * Perform NCQ error analysis on failed PMPs
+		 * before we freeze the port entirely.
+		 *
+		 * The failed PMPs are marked earlier by mv_pmp_eh_prep().
+		 */
+		pmp_map = pp->delayed_eh_pmp_map;
+		pp->pp_flags &= ~MV_PP_FLAG_DELAYED_EH;
+		for (pmp = 0; pmp_map != 0; pmp++) {
+			unsigned int this_pmp = (1 << pmp);
+			if (pmp_map & this_pmp) {
+				struct ata_link *link = &ap->pmp_link[pmp];
+				pmp_map &= ~this_pmp;
+				ata_eh_analyze_ncq_error(link);
+			}
+		}
+		ata_port_freeze(ap);
+	}
+	sata_pmp_error_handler(ap);
+}
+
+static unsigned int mv_get_err_pmp_map(struct ata_port *ap)
+{
+	void __iomem *port_mmio = mv_ap_base(ap);
+
+	return readl(port_mmio + SATA_TESTCTL_OFS) >> 16;
+}
+
+static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map)
+{
+	struct ata_eh_info *ehi;
+	unsigned int pmp;
 
 	/*
-	 * We got a device interrupt from something that
-	 * was supposed to be using EDMA or polling.
+	 * Initialize EH info for PMPs which saw device errors
 	 */
+	ehi = &ap->link.eh_info;
+	for (pmp = 0; pmp_map != 0; pmp++) {
+		unsigned int this_pmp = (1 << pmp);
+		if (pmp_map & this_pmp) {
+			struct ata_link *link = &ap->pmp_link[pmp];
+
+			pmp_map &= ~this_pmp;
+			ehi = &link->eh_info;
+			ata_ehi_clear_desc(ehi);
+			ata_ehi_push_desc(ehi, "dev err");
+			ehi->err_mask |= AC_ERR_DEV;
+			ehi->action |= ATA_EH_RESET;
+			ata_link_abort(link);
+		}
+	}
+}
+
+static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap)
+{
+	struct mv_port_priv *pp = ap->private_data;
+	int failed_links;
+	unsigned int old_map, new_map;
+
+	/*
+	 * Device error during FBS+NCQ operation:
+	 *
+	 * Set a port flag to prevent further I/O being enqueued.
+	 * Leave the EDMA running to drain outstanding commands from this port.
+	 * Perform the post-mortem/EH only when all responses are complete.
+	 * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.2).
+	 */
+	if (!(pp->pp_flags & MV_PP_FLAG_DELAYED_EH)) {
+		pp->pp_flags |= MV_PP_FLAG_DELAYED_EH;
+		pp->delayed_eh_pmp_map = 0;
+	}
+	old_map = pp->delayed_eh_pmp_map;
+	new_map = old_map | mv_get_err_pmp_map(ap);
+
+	if (old_map != new_map) {
+		pp->delayed_eh_pmp_map = new_map;
+		mv_pmp_eh_prep(ap, new_map & ~old_map);
+	}
+	failed_links = hweight16(new_map);
+
+	ata_port_printk(ap, KERN_INFO, "%s: pmp_map=%04x qc_map=%04x "
+			"failed_links=%d nr_active_links=%d\n",
+			__func__, pp->delayed_eh_pmp_map,
+			ap->qc_active, failed_links,
+			ap->nr_active_links);
+
+	if (ap->nr_active_links <= failed_links) {
+		mv_process_crpb_entries(ap, pp);
+		mv_stop_edma(ap);
+		mv_eh_freeze(ap);
+		ata_port_printk(ap, KERN_INFO, "%s: done\n", __func__);
+		return 1;	/* handled */
+	}
+	ata_port_printk(ap, KERN_INFO, "%s: waiting\n", __func__);
+	return 1;	/* handled */
+}
+
+static int mv_handle_fbs_non_ncq_dev_err(struct ata_port *ap)
+{
+	/*
+	 * Possible future enhancement:
+	 *
+	 * FBS+non-NCQ operation is not yet implemented.
+	 * See related notes in mv_edma_cfg().
+	 *
+	 * Device error during FBS+non-NCQ operation:
+	 *
+	 * We need to snapshot the shadow registers for each failed command.
+	 * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.3).
+	 */
+	return 0;	/* not handled */
+}
+
+static int mv_handle_dev_err(struct ata_port *ap, u32 edma_err_cause)
+{
+	struct mv_port_priv *pp = ap->private_data;
+
+	if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
+		return 0;	/* EDMA was not active: not handled */
+	if (!(pp->pp_flags & MV_PP_FLAG_FBS_EN))
+		return 0;	/* FBS was not active: not handled */
+
+	if (!(edma_err_cause & EDMA_ERR_DEV))
+		return 0;	/* non DEV error: not handled */
+	edma_err_cause &= ~EDMA_ERR_IRQ_TRANSIENT;
+	if (edma_err_cause & ~(EDMA_ERR_DEV | EDMA_ERR_SELF_DIS))
+		return 0;	/* other problems: not handled */
+
+	if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
+		/*
+		 * EDMA should NOT have self-disabled for this case.
+		 * If it did, then something is wrong elsewhere,
+		 * and we cannot handle it here.
+		 */
+		if (edma_err_cause & EDMA_ERR_SELF_DIS) {
+			ata_port_printk(ap, KERN_WARNING,
+				"%s: err_cause=0x%x pp_flags=0x%x\n",
+				__func__, edma_err_cause, pp->pp_flags);
+			return 0; /* not handled */
+		}
+		return mv_handle_fbs_ncq_dev_err(ap);
+	} else {
+		/*
+		 * EDMA should have self-disabled for this case.
+		 * If it did not, then something is wrong elsewhere,
+		 * and we cannot handle it here.
+		 */
+		if (!(edma_err_cause & EDMA_ERR_SELF_DIS)) {
+			ata_port_printk(ap, KERN_WARNING,
+				"%s: err_cause=0x%x pp_flags=0x%x\n",
+				__func__, edma_err_cause, pp->pp_flags);
+			return 0; /* not handled */
+		}
+		return mv_handle_fbs_non_ncq_dev_err(ap);
+	}
+	return 0;	/* not handled */
+}
+
+static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled)
+{
+	struct ata_eh_info *ehi = &ap->link.eh_info;
+	char *when = "idle";
+
 	ata_ehi_clear_desc(ehi);
-	if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
-		when = " while EDMA enabled";
+	if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+		when = "disabled";
+	} else if (edma_was_enabled) {
+		when = "EDMA enabled";
 	} else {
 		struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
 		if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
-			when = " while polling";
+			when = "polling";
 	}
-	ata_ehi_push_desc(ehi, "unexpected device interrupt%s", when);
+	ata_ehi_push_desc(ehi, "unexpected device interrupt while %s", when);
 	ehi->err_mask |= AC_ERR_OTHER;
 	ehi->action   |= ATA_EH_RESET;
 	ata_port_freeze(ap);
@@ -1519,7 +1808,7 @@
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
+static void mv_err_intr(struct ata_port *ap)
 {
 	void __iomem *port_mmio = mv_ap_base(ap);
 	u32 edma_err_cause, eh_freeze_mask, serr = 0;
@@ -1527,24 +1816,42 @@
 	struct mv_host_priv *hpriv = ap->host->private_data;
 	unsigned int action = 0, err_mask = 0;
 	struct ata_eh_info *ehi = &ap->link.eh_info;
-
-	ata_ehi_clear_desc(ehi);
+	struct ata_queued_cmd *qc;
+	int abort = 0;
 
 	/*
-	 * Read and clear the err_cause bits.  This won't actually
-	 * clear for some errors (eg. SError), but we will be doing
-	 * a hard reset in those cases regardless, which *will* clear it.
+	 * Read and clear the SError and err_cause bits.
 	 */
+	sata_scr_read(&ap->link, SCR_ERROR, &serr);
+	sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
+
 	edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 	writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
-	ata_ehi_push_desc(ehi, "edma_err_cause=%08x", edma_err_cause);
+	ata_port_printk(ap, KERN_INFO, "%s: err_cause=%08x pp_flags=0x%x\n",
+			__func__, edma_err_cause, pp->pp_flags);
 
+	if (edma_err_cause & EDMA_ERR_DEV) {
+		/*
+		 * Device errors during FIS-based switching operation
+		 * require special handling.
+		 */
+		if (mv_handle_dev_err(ap, edma_err_cause))
+			return;
+	}
+
+	qc = mv_get_active_qc(ap);
+	ata_ehi_clear_desc(ehi);
+	ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x",
+			  edma_err_cause, pp->pp_flags);
 	/*
 	 * All generations share these EDMA error cause bits:
 	 */
-	if (edma_err_cause & EDMA_ERR_DEV)
+	if (edma_err_cause & EDMA_ERR_DEV) {
 		err_mask |= AC_ERR_DEV;
+		action |= ATA_EH_RESET;
+		ata_ehi_push_desc(ehi, "dev error");
+	}
 	if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
 			EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR |
 			EDMA_ERR_INTRL_PAR)) {
@@ -1576,13 +1883,6 @@
 			ata_ehi_push_desc(ehi, "EDMA self-disable");
 		}
 		if (edma_err_cause & EDMA_ERR_SERR) {
-			/*
-			 * Ensure that we read our own SCR, not a pmp link SCR:
-			 */
-			ap->ops->scr_read(ap, SCR_ERROR, &serr);
-			/*
-			 * Don't clear SError here; leave it for libata-eh:
-			 */
 			ata_ehi_push_desc(ehi, "SError=%08x", serr);
 			err_mask |= AC_ERR_ATA_BUS;
 			action |= ATA_EH_RESET;
@@ -1602,10 +1902,29 @@
 	else
 		ehi->err_mask |= err_mask;
 
-	if (edma_err_cause & eh_freeze_mask)
+	if (err_mask == AC_ERR_DEV) {
+		/*
+		 * Cannot do ata_port_freeze() here,
+		 * because it would kill PIO access,
+		 * which is needed for further diagnosis.
+		 */
+		mv_eh_freeze(ap);
+		abort = 1;
+	} else if (edma_err_cause & eh_freeze_mask) {
+		/*
+		 * Note to self: ata_port_freeze() calls ata_port_abort()
+		 */
 		ata_port_freeze(ap);
-	else
-		ata_port_abort(ap);
+	} else {
+		abort = 1;
+	}
+
+	if (abort) {
+		if (qc)
+			ata_link_abort(qc->dev->link);
+		else
+			ata_port_abort(ap);
+	}
 }
 
 static void mv_process_crpb_response(struct ata_port *ap,
@@ -1632,8 +1951,9 @@
 			}
 		}
 		ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
-		qc->err_mask |= ac_err_mask(ata_status);
-		ata_qc_complete(qc);
+		if (!ac_err_mask(ata_status))
+			ata_qc_complete(qc);
+		/* else: leave it for mv_err_intr() */
 	} else {
 		ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
 				__func__, tag);
@@ -1677,6 +1997,44 @@
 			 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 }
 
+static void mv_port_intr(struct ata_port *ap, u32 port_cause)
+{
+	struct mv_port_priv *pp;
+	int edma_was_enabled;
+
+	if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+		mv_unexpected_intr(ap, 0);
+		return;
+	}
+	/*
+	 * Grab a snapshot of the EDMA_EN flag setting,
+	 * so that we have a consistent view for this port,
+	 * even if something we call of our routines changes it.
+	 */
+	pp = ap->private_data;
+	edma_was_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN);
+	/*
+	 * Process completed CRPB response(s) before other events.
+	 */
+	if (edma_was_enabled && (port_cause & DONE_IRQ)) {
+		mv_process_crpb_entries(ap, pp);
+		if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH)
+			mv_handle_fbs_ncq_dev_err(ap);
+	}
+	/*
+	 * Handle chip-reported errors, or continue on to handle PIO.
+	 */
+	if (unlikely(port_cause & ERR_IRQ)) {
+		mv_err_intr(ap);
+	} else if (!edma_was_enabled) {
+		struct ata_queued_cmd *qc = mv_get_active_qc(ap);
+		if (qc)
+			ata_sff_host_intr(ap, qc);
+		else
+			mv_unexpected_intr(ap, edma_was_enabled);
+	}
+}
+
 /**
  *      mv_host_intr - Handle all interrupts on the given host controller
  *      @host: host specific structure
@@ -1688,66 +2046,58 @@
 static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
 {
 	struct mv_host_priv *hpriv = host->private_data;
-	void __iomem *mmio = hpriv->base, *hc_mmio = NULL;
-	u32 hc_irq_cause = 0;
+	void __iomem *mmio = hpriv->base, *hc_mmio;
 	unsigned int handled = 0, port;
 
 	for (port = 0; port < hpriv->n_ports; port++) {
 		struct ata_port *ap = host->ports[port];
-		struct mv_port_priv *pp;
-		unsigned int shift, hardport, port_cause;
-		/*
-		 * When we move to the second hc, flag our cached
-		 * copies of hc_mmio (and hc_irq_cause) as invalid again.
-		 */
-		if (port == MV_PORTS_PER_HC)
-			hc_mmio = NULL;
-		/*
-		 * Do nothing if port is not interrupting or is disabled:
-		 */
+		unsigned int p, shift, hardport, port_cause;
+
 		MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport);
-		port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ);
-		if (!port_cause || !ap || (ap->flags & ATA_FLAG_DISABLED))
-			continue;
 		/*
-		 * Each hc within the host has its own hc_irq_cause register.
-		 * We defer reading it until we know we need it, right now:
-		 *
-		 * FIXME later: we don't really need to read this register
-		 * (some logic changes required below if we go that way),
-		 * because it doesn't tell us anything new.  But we do need
-		 * to write to it, outside the top of this loop,
-		 * to reset the interrupt triggers for next time.
+		 * Each hc within the host has its own hc_irq_cause register,
+		 * where the interrupting ports bits get ack'd.
 		 */
-		if (!hc_mmio) {
+		if (hardport == 0) {	/* first port on this hc ? */
+			u32 hc_cause = (main_irq_cause >> shift) & HC0_IRQ_PEND;
+			u32 port_mask, ack_irqs;
+			/*
+			 * Skip this entire hc if nothing pending for any ports
+			 */
+			if (!hc_cause) {
+				port += MV_PORTS_PER_HC - 1;
+				continue;
+			}
+			/*
+			 * We don't need/want to read the hc_irq_cause register,
+			 * because doing so hurts performance, and
+			 * main_irq_cause already gives us everything we need.
+			 *
+			 * But we do have to *write* to the hc_irq_cause to ack
+			 * the ports that we are handling this time through.
+			 *
+			 * This requires that we create a bitmap for those
+			 * ports which interrupted us, and use that bitmap
+			 * to ack (only) those ports via hc_irq_cause.
+			 */
+			ack_irqs = 0;
+			for (p = 0; p < MV_PORTS_PER_HC; ++p) {
+				if ((port + p) >= hpriv->n_ports)
+					break;
+				port_mask = (DONE_IRQ | ERR_IRQ) << (p * 2);
+				if (hc_cause & port_mask)
+					ack_irqs |= (DMA_IRQ | DEV_IRQ) << p;
+			}
 			hc_mmio = mv_hc_base_from_port(mmio, port);
-			hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
-			writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+			writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS);
 			handled = 1;
 		}
 		/*
-		 * Process completed CRPB response(s) before other events.
+		 * Handle interrupts signalled for this port:
 		 */
-		pp = ap->private_data;
-		if (hc_irq_cause & (DMA_IRQ << hardport)) {
-			if (pp->pp_flags & MV_PP_FLAG_EDMA_EN)
-				mv_process_crpb_entries(ap, pp);
-		}
-		/*
-		 * Handle chip-reported errors, or continue on to handle PIO.
-		 */
-		if (unlikely(port_cause & ERR_IRQ)) {
-			mv_err_intr(ap, mv_get_active_qc(ap));
-		} else if (hc_irq_cause & (DEV_IRQ << hardport)) {
-			if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
-				struct ata_queued_cmd *qc = mv_get_active_qc(ap);
-				if (qc) {
-					ata_sff_host_intr(ap, qc);
-					continue;
-				}
-			}
-			mv_unexpected_intr(ap);
-		}
+		port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ);
+		if (port_cause)
+			mv_port_intr(ap, port_cause);
 	}
 	return handled;
 }
@@ -1894,7 +2244,7 @@
 
 static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
 {
-	writel(0x0fcfffff, mmio + MV_FLASH_CTL);
+	writel(0x0fcfffff, mmio + MV_FLASH_CTL_OFS);
 }
 
 static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
@@ -1913,7 +2263,7 @@
 {
 	u32 tmp;
 
-	writel(0, mmio + MV_GPIO_PORT_CTL);
+	writel(0, mmio + MV_GPIO_PORT_CTL_OFS);
 
 	/* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
 
@@ -1931,14 +2281,14 @@
 	int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0);
 
 	if (fix_apm_sq) {
-		tmp = readl(phy_mmio + MV5_LT_MODE);
+		tmp = readl(phy_mmio + MV5_LTMODE_OFS);
 		tmp |= (1 << 19);
-		writel(tmp, phy_mmio + MV5_LT_MODE);
+		writel(tmp, phy_mmio + MV5_LTMODE_OFS);
 
-		tmp = readl(phy_mmio + MV5_PHY_CTL);
+		tmp = readl(phy_mmio + MV5_PHY_CTL_OFS);
 		tmp &= ~0x3;
 		tmp |= 0x1;
-		writel(tmp, phy_mmio + MV5_PHY_CTL);
+		writel(tmp, phy_mmio + MV5_PHY_CTL_OFS);
 	}
 
 	tmp = readl(phy_mmio + MV5_PHY_MODE);
@@ -1956,11 +2306,6 @@
 {
 	void __iomem *port_mmio = mv_port_base(mmio, port);
 
-	/*
-	 * The datasheet warns against setting ATA_RST when EDMA is active
-	 * (but doesn't say what the problem might be).  So we first try
-	 * to disable the EDMA engine before doing the ATA_RST operation.
-	 */
 	mv_reset_channel(hpriv, mmio, port);
 
 	ZERO(0x028);	/* command */
@@ -1975,7 +2320,7 @@
 	ZERO(0x024);	/* respq outp */
 	ZERO(0x020);	/* respq inp */
 	ZERO(0x02c);	/* test control */
-	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS);
 }
 #undef ZERO
 
@@ -2021,13 +2366,13 @@
 	struct mv_host_priv *hpriv = host->private_data;
 	u32 tmp;
 
-	tmp = readl(mmio + MV_PCI_MODE);
+	tmp = readl(mmio + MV_PCI_MODE_OFS);
 	tmp &= 0xff00ffff;
-	writel(tmp, mmio + MV_PCI_MODE);
+	writel(tmp, mmio + MV_PCI_MODE_OFS);
 
 	ZERO(MV_PCI_DISC_TIMER);
 	ZERO(MV_PCI_MSI_TRIGGER);
-	writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT);
+	writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS);
 	ZERO(PCI_HC_MAIN_IRQ_MASK_OFS);
 	ZERO(MV_PCI_SERR_MASK);
 	ZERO(hpriv->irq_cause_ofs);
@@ -2045,10 +2390,10 @@
 
 	mv5_reset_flash(hpriv, mmio);
 
-	tmp = readl(mmio + MV_GPIO_PORT_CTL);
+	tmp = readl(mmio + MV_GPIO_PORT_CTL_OFS);
 	tmp &= 0x3;
 	tmp |= (1 << 5) | (1 << 6);
-	writel(tmp, mmio + MV_GPIO_PORT_CTL);
+	writel(tmp, mmio + MV_GPIO_PORT_CTL_OFS);
 }
 
 /**
@@ -2121,7 +2466,7 @@
 	void __iomem *port_mmio;
 	u32 tmp;
 
-	tmp = readl(mmio + MV_RESET_CFG);
+	tmp = readl(mmio + MV_RESET_CFG_OFS);
 	if ((tmp & (1 << 0)) == 0) {
 		hpriv->signal[idx].amps = 0x7 << 8;
 		hpriv->signal[idx].pre = 0x1 << 5;
@@ -2137,7 +2482,7 @@
 
 static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
 {
-	writel(0x00000060, mmio + MV_GPIO_PORT_CTL);
+	writel(0x00000060, mmio + MV_GPIO_PORT_CTL_OFS);
 }
 
 static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -2235,11 +2580,6 @@
 {
 	void __iomem *port_mmio = mv_port_base(mmio, port);
 
-	/*
-	 * The datasheet warns against setting ATA_RST when EDMA is active
-	 * (but doesn't say what the problem might be).  So we first try
-	 * to disable the EDMA engine before doing the ATA_RST operation.
-	 */
 	mv_reset_channel(hpriv, mmio, port);
 
 	ZERO(0x028);		/* command */
@@ -2254,7 +2594,7 @@
 	ZERO(0x024);		/* respq outp */
 	ZERO(0x020);		/* respq inp */
 	ZERO(0x02c);		/* test control */
-	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS);
 }
 
 #undef ZERO
@@ -2297,38 +2637,39 @@
 	return;
 }
 
-static void mv_setup_ifctl(void __iomem *port_mmio, int want_gen2i)
+static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
 {
-	u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG);
+	u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS);
 
-	ifctl = (ifctl & 0xf7f) | 0x9b1000;	/* from chip spec */
+	ifcfg = (ifcfg & 0xf7f) | 0x9b1000;	/* from chip spec */
 	if (want_gen2i)
-		ifctl |= (1 << 7);		/* enable gen2i speed */
-	writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG);
+		ifcfg |= (1 << 7);		/* enable gen2i speed */
+	writelfl(ifcfg, port_mmio + SATA_INTERFACE_CFG_OFS);
 }
 
-/*
- * Caller must ensure that EDMA is not active,
- * by first doing mv_stop_edma() where needed.
- */
 static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
 			     unsigned int port_no)
 {
 	void __iomem *port_mmio = mv_port_base(mmio, port_no);
 
+	/*
+	 * The datasheet warns against setting EDMA_RESET when EDMA is active
+	 * (but doesn't say what the problem might be).  So we first try
+	 * to disable the EDMA engine before doing the EDMA_RESET operation.
+	 */
 	mv_stop_edma_engine(port_mmio);
-	writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+	writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
 
 	if (!IS_GEN_I(hpriv)) {
-		/* Enable 3.0gb/s link speed */
-		mv_setup_ifctl(port_mmio, 1);
+		/* Enable 3.0gb/s link speed: this survives EDMA_RESET */
+		mv_setup_ifcfg(port_mmio, 1);
 	}
 	/*
-	 * Strobing ATA_RST here causes a hard reset of the SATA transport,
+	 * Strobing EDMA_RESET here causes a hard reset of the SATA transport,
 	 * link, and physical layers.  It resets all SATA interface registers
 	 * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev.
 	 */
-	writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+	writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
 	udelay(25);	/* allow reset propagation */
 	writelfl(0, port_mmio + EDMA_CMD_OFS);
 
@@ -2392,7 +2733,7 @@
 		sata_scr_read(link, SCR_STATUS, &sstatus);
 		if (!IS_GEN_I(hpriv) && ++attempts >= 5 && sstatus == 0x121) {
 			/* Force 1.5gb/s link speed and try again */
-			mv_setup_ifctl(mv_ap_base(ap), 0);
+			mv_setup_ifcfg(mv_ap_base(ap), 0);
 			if (time_after(jiffies + HZ, deadline))
 				extra = HZ; /* only extend it once, max */
 		}
@@ -2493,6 +2834,34 @@
 		readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
 }
 
+static unsigned int mv_in_pcix_mode(struct ata_host *host)
+{
+	struct mv_host_priv *hpriv = host->private_data;
+	void __iomem *mmio = hpriv->base;
+	u32 reg;
+
+	if (!HAS_PCI(host) || !IS_PCIE(hpriv))
+		return 0;	/* not PCI-X capable */
+	reg = readl(mmio + MV_PCI_MODE_OFS);
+	if ((reg & MV_PCI_MODE_MASK) == 0)
+		return 0;	/* conventional PCI mode */
+	return 1;	/* chip is in PCI-X mode */
+}
+
+static int mv_pci_cut_through_okay(struct ata_host *host)
+{
+	struct mv_host_priv *hpriv = host->private_data;
+	void __iomem *mmio = hpriv->base;
+	u32 reg;
+
+	if (!mv_in_pcix_mode(host)) {
+		reg = readl(mmio + PCI_COMMAND_OFS);
+		if (reg & PCI_COMMAND_MRDTRIG)
+			return 0; /* not okay */
+	}
+	return 1; /* okay */
+}
+
 static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 {
 	struct pci_dev *pdev = to_pci_dev(host->dev);
@@ -2560,7 +2929,7 @@
 		break;
 
 	case chip_7042:
-		hp_flags |= MV_HP_PCIE;
+		hp_flags |= MV_HP_PCIE | MV_HP_CUT_THROUGH;
 		if (pdev->vendor == PCI_VENDOR_ID_TTI &&
 		    (pdev->device == 0x2300 || pdev->device == 0x2310))
 		{
@@ -2590,9 +2959,12 @@
 				" and avoid the final two gigabytes on"
 				" all RocketRAID BIOS initialized drives.\n");
 		}
+		/* drop through */
 	case chip_6042:
 		hpriv->ops = &mv6xxx_ops;
 		hp_flags |= MV_HP_GEN_IIE;
+		if (board_idx == chip_6042 && mv_pci_cut_through_okay(host))
+			hp_flags |= MV_HP_CUT_THROUGH;
 
 		switch (pdev->revision) {
 		case 0x0:
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h
index 133eefc..b2cd20f 100644
--- a/drivers/atm/iphase.h
+++ b/drivers/atm/iphase.h
@@ -1025,7 +1025,8 @@
         spinlock_t rx_lock, misc_lock;
 	struct atm_vcc **rx_open;	/* list of all open VCs */  
         u16 num_rx_desc, rx_buf_sz, rxing;
-        u32 rx_pkt_ram, rx_tmp_cnt, rx_tmp_jif;
+        u32 rx_pkt_ram, rx_tmp_cnt;
+        unsigned long rx_tmp_jif;
         void __iomem *RX_DESC_BASE_ADDR;
         u32 drop_rxpkt, drop_rxcell, rx_cell_cnt, rx_pkt_cnt;
 	struct atm_dev *next_board;	/* other iphase devices */  
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 0ef00e8..e085af0 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -140,7 +140,6 @@
 
 	pr_debug("device class '%s': registering\n", cls->name);
 
-	INIT_LIST_HEAD(&cls->children);
 	INIT_LIST_HEAD(&cls->devices);
 	INIT_LIST_HEAD(&cls->interfaces);
 	kset_init(&cls->class_dirs);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index be288b5..3eeac5a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1218,13 +1218,11 @@
 	}
 #else
 	if (dev->class) {
-		sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
 		error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
 					  dev->bus_id);
-		if (error) {
-			dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
-				__func__, error);
-		}
+		if (error)
+			goto out;
+		sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
 	}
 #endif
 
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 8ce6de5..937e825 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -53,11 +53,13 @@
 {
         return blocking_notifier_chain_register(&memory_chain, nb);
 }
+EXPORT_SYMBOL(register_memory_notifier);
 
 void unregister_memory_notifier(struct notifier_block *nb)
 {
         blocking_notifier_chain_unregister(&memory_chain, nb);
 }
+EXPORT_SYMBOL(unregister_memory_notifier);
 
 /*
  * register_memory - Setup a sysfs device for a memory block
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 4fbb56b..358bb0b 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -175,8 +175,7 @@
 	}
 
 	/* Check whether this driver has already been added to a class. */
-	if ((drv->entry.next != drv->entry.prev) ||
-	    (drv->entry.next != NULL)) {
+	if (drv->entry.next && !list_empty(&drv->entry)) {
 		printk(KERN_WARNING "sysdev: class %s: driver (%p) has already"
 			" been registered to a class, something is wrong, but "
 			"will forge on!\n", cls->name, drv);
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 8fc429c..41f818b 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -755,11 +755,13 @@
 {
 	unsigned long n_sect = bio->bi_size >> 9;
 	const int rw = bio_data_dir(bio);
+	struct hd_struct *part;
 
-	all_stat_inc(disk, ios[rw], sector);
-	all_stat_add(disk, ticks[rw], duration, sector);
-	all_stat_add(disk, sectors[rw], n_sect, sector);
-	all_stat_add(disk, io_ticks, duration, sector);
+	part = get_part(disk, sector);
+	all_stat_inc(disk, part, ios[rw], sector);
+	all_stat_add(disk, part, ticks[rw], duration, sector);
+	all_stat_add(disk, part, sectors[rw], n_sect, sector);
+	all_stat_add(disk, part, io_ticks, duration, sector);
 }
 
 void
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 5dce387..595a925 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -196,6 +196,7 @@
 config MOXA_INTELLIO
 	tristate "Moxa Intellio support"
 	depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
+	select FW_LOADER
 	help
 	  Say Y here if you have a Moxa Intellio multiport serial card.
 
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 5a54555..1926883 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2352,10 +2352,16 @@
 
 	info->si_type		= (enum si_type) match->data;
 	info->addr_source	= "device-tree";
-	info->io_setup		= mem_setup;
 	info->irq_setup		= std_irq_setup;
 
-	info->io.addr_type	= IPMI_MEM_ADDR_SPACE;
+	if (resource.flags & IORESOURCE_IO) {
+		info->io_setup		= port_setup;
+		info->io.addr_type	= IPMI_IO_ADDR_SPACE;
+	} else {
+		info->io_setup		= mem_setup;
+		info->io.addr_type	= IPMI_MEM_ADDR_SPACE;
+	}
+
 	info->io.addr_data	= resource.start;
 
 	info->io.regsize	= regsize ? *regsize : DEFAULT_REGSIZE;
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index fd2db07..3b23270 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -1073,7 +1073,7 @@
 		return 0;
 
 	if (!info->xmit_buf)
-		return;
+		return 0;
 
 	local_irq_save(flags);
 	if (info->xmit_cnt >= PAGE_SIZE - 1) {
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index f39f6fd..b1a7a8c 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -970,7 +970,8 @@
 		sx_write_channel_byte(port, hi_mask, 0x1f);
 		break;
 	default:
-		printk(KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE);
+		printk(KERN_INFO "sx: Invalid wordsize: %u\n",
+			(unsigned int)CFLAG & CSIZE);
 		break;
 	}
 
@@ -997,7 +998,8 @@
 		set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
 	}
 	sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
-			port->gs.tty->termios->c_iflag, I_OTHER(port->gs.tty));
+			(unsigned int)port->gs.tty->termios->c_iflag,
+			I_OTHER(port->gs.tty));
 
 /* Tell line discipline whether we will do output cooking.
  * If OPOST is set and no other output flags are set then we can do output
@@ -1010,7 +1012,8 @@
 		clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
 	}
 	sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
-			port->gs.tty->termios->c_oflag, O_OTHER(port->gs.tty));
+			(unsigned int)port->gs.tty->termios->c_oflag,
+			O_OTHER(port->gs.tty));
 	/* port->c_dcd = sx_get_CD (port); */
 	func_exit();
 	return 0;
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 2001b0e..55c1653 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -916,7 +916,7 @@
 {
 	struct slgt_info *info = tty->driver_data;
 	unsigned long flags;
-	int ret;
+	int ret = 0;
 
 	if (sanity_check(info, tty->name, "put_char"))
 		return 0;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 49c1a22..e94bee0 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1215,10 +1215,11 @@
 
 	if (!tty->pgrp) {
 		printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
-		goto out;
+		goto out_unlock;
 	}
 	if (task_pgrp(current) == tty->pgrp)
-		goto out;
+		goto out_unlock;
+	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 	if (is_ignored(SIGTTOU))
 		goto out;
 	if (is_current_pgrp_orphaned()) {
@@ -1229,6 +1230,8 @@
 	set_thread_flag(TIF_SIGPENDING);
 	ret = -ERESTARTSYS;
 out:
+	return ret;
+out_unlock:
 	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 	return ret;
 }
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index e458b08..fa1ffbf 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2742,6 +2742,10 @@
 				tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
 				tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
 			}
+			if (vc->vc_utf)
+				tty->termios->c_iflag |= IUTF8;
+			else
+				tty->termios->c_iflag &= ~IUTF8;
 			release_console_sem();
 			vcs_make_sysfs(tty);
 			return ret;
@@ -2918,6 +2922,8 @@
 	console_driver->minor_start = 1;
 	console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
 	console_driver->init_termios = tty_std_termios;
+	if (default_utf8)
+		console_driver->init_termios.c_iflag |= IUTF8;
 	console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
 	tty_set_operations(console_driver, &con_ops);
 	if (tty_register_driver(console_driver))
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index a9aa845..b27b13c 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -97,7 +97,7 @@
 #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
 	PCI_DEVICE_ID_ ## vend ## _ ## dev
 
-#define dev_name(dev) (dev)->dev_name
+#define edac_dev_name(dev) (dev)->dev_name
 
 /* memory devices */
 enum dev_type {
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index 63372fa..5fcd3d8 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -333,7 +333,7 @@
 fail0:
 	edac_printk(KERN_WARNING, EDAC_MC,
 			"%s (%s) %s %s already assigned %d\n",
-			rover->dev->bus_id, dev_name(rover),
+			rover->dev->bus_id, edac_dev_name(rover),
 			rover->mod_name, rover->ctl_name, rover->dev_idx);
 	return 1;
 
@@ -538,7 +538,7 @@
 				"'%s': DEV '%s' (%s)\n",
 				edac_dev->mod_name,
 				edac_dev->ctl_name,
-				dev_name(edac_dev),
+				edac_dev_name(edac_dev),
 				edac_op_state_to_string(edac_dev->op_state));
 
 	mutex_unlock(&device_ctls_mutex);
@@ -599,7 +599,7 @@
 	edac_printk(KERN_INFO, EDAC_MC,
 		"Removed device %d for %s %s: DEV %s\n",
 		edac_dev->dev_idx,
-		edac_dev->mod_name, edac_dev->ctl_name, dev_name(edac_dev));
+		edac_dev->mod_name, edac_dev->ctl_name, edac_dev_name(edac_dev));
 
 	return edac_dev;
 }
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index a4cf164..d110392 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -402,7 +402,7 @@
 fail0:
 	edac_printk(KERN_WARNING, EDAC_MC,
 		"%s (%s) %s %s already assigned %d\n", p->dev->bus_id,
-		dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
+		edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
 	return 1;
 
 fail1:
@@ -517,7 +517,7 @@
 
 	/* Report action taken */
 	edac_mc_printk(mci, KERN_INFO, "Giving out device to '%s' '%s':"
-		" DEV %s\n", mci->mod_name, mci->ctl_name, dev_name(mci));
+		" DEV %s\n", mci->mod_name, mci->ctl_name, edac_dev_name(mci));
 
 	mutex_unlock(&mem_ctls_mutex);
 	return 0;
@@ -565,7 +565,7 @@
 
 	edac_printk(KERN_INFO, EDAC_MC,
 		"Removed device %d for %s %s: DEV %s\n", mci->mc_idx,
-		mci->mod_name, mci->ctl_name, dev_name(mci));
+		mci->mod_name, mci->ctl_name, edac_dev_name(mci));
 
 	return mci;
 }
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c
index 9b24340..22ec9d5 100644
--- a/drivers/edac/edac_pci.c
+++ b/drivers/edac/edac_pci.c
@@ -150,7 +150,7 @@
 fail0:
 	edac_printk(KERN_WARNING, EDAC_PCI,
 		"%s (%s) %s %s already assigned %d\n",
-		rover->dev->bus_id, dev_name(rover),
+		rover->dev->bus_id, edac_dev_name(rover),
 		rover->mod_name, rover->ctl_name, rover->pci_idx);
 	return 1;
 
@@ -360,7 +360,7 @@
 			" DEV '%s' (%s)\n",
 			pci->mod_name,
 			pci->ctl_name,
-			dev_name(pci), edac_op_state_to_string(pci->op_state));
+			edac_dev_name(pci), edac_op_state_to_string(pci->op_state));
 
 	mutex_unlock(&edac_pci_ctls_mutex);
 	return 0;
@@ -415,7 +415,7 @@
 
 	edac_printk(KERN_INFO, EDAC_PCI,
 		"Removed device %d for %s %s: DEV %s\n",
-		pci->pci_idx, pci->mod_name, pci->ctl_name, dev_name(pci));
+		pci->pci_idx, pci->mod_name, pci->ctl_name, edac_dev_name(pci));
 
 	return pci;
 }
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index 491718f..cae9dc8 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -335,7 +335,7 @@
 		goto out_mem;
 	}
 
-	priv->psc_base = r->start;
+	priv->psc_base = CKSEG1ADDR(r->start);
 	priv->xfer_timeout = 200;
 	priv->ack_timeout = 200;
 
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 18beb0a..a076129 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -99,7 +99,7 @@
 	u32 x;
 	int result = 0;
 
-	if (i2c->irq == 0)
+	if (i2c->irq == NO_IRQ)
 	{
 		while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
 			schedule();
@@ -329,10 +329,9 @@
 		return -ENOMEM;
 
 	i2c->irq = platform_get_irq(pdev, 0);
-	if (i2c->irq < 0) {
-		result = -ENXIO;
-		goto fail_get_irq;
-	}
+	if (i2c->irq < 0)
+		i2c->irq = NO_IRQ; /* Use polling */
+
 	i2c->flags = pdata->device_flags;
 	init_waitqueue_head(&i2c->queue);
 
@@ -344,7 +343,7 @@
 		goto fail_map;
 	}
 
-	if (i2c->irq != 0)
+	if (i2c->irq != NO_IRQ)
 		if ((result = request_irq(i2c->irq, mpc_i2c_isr,
 					  IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
 			printk(KERN_ERR
@@ -367,12 +366,11 @@
 	return result;
 
       fail_add:
-	if (i2c->irq != 0)
+	if (i2c->irq != NO_IRQ)
 		free_irq(i2c->irq, i2c);
       fail_irq:
 	iounmap(i2c->base);
       fail_map:
-      fail_get_irq:
 	kfree(i2c);
 	return result;
 };
@@ -384,7 +382,7 @@
 	i2c_del_adapter(&i2c->adap);
 	platform_set_drvdata(pdev, NULL);
 
-	if (i2c->irq != 0)
+	if (i2c->irq != NO_IRQ)
 		free_irq(i2c->irq, i2c);
 
 	iounmap(i2c->base);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index fdc9ad8..ac91659 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -104,10 +104,31 @@
 static int piix4_transaction(void);
 
 static unsigned short piix4_smba;
+static int srvrworks_csb5_delay;
 static struct pci_driver piix4_driver;
 static struct i2c_adapter piix4_adapter;
 
-static struct dmi_system_id __devinitdata piix4_dmi_table[] = {
+static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
+	{
+		.ident = "Sapphire AM2RD790",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
+			DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
+		},
+	},
+	{
+		.ident = "DFI Lanparty UT 790FX",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
+			DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
+		},
+	},
+	{ }
+};
+
+/* The IBM entry is in a separate table because we only check it
+   on Intel-based systems */
+static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
 	{
 		.ident = "IBM",
 		.matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
@@ -122,8 +143,20 @@
 
 	dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
 
+	if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
+	    (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
+		srvrworks_csb5_delay = 1;
+
+	/* On some motherboards, it was reported that accessing the SMBus
+	   caused severe hardware problems */
+	if (dmi_check_system(piix4_dmi_blacklist)) {
+		dev_err(&PIIX4_dev->dev,
+			"Accessing the SMBus on this system is unsafe!\n");
+		return -EPERM;
+	}
+
 	/* Don't access SMBus on IBM systems which get corrupted eeproms */
-	if (dmi_check_system(piix4_dmi_table) &&
+	if (dmi_check_system(piix4_dmi_ibm) &&
 			PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
 		dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
 			"may corrupt your serial eeprom! Refusing to load "
@@ -230,10 +263,14 @@
 	outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
 
 	/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
-	do {
+	if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
+		msleep(2);
+	else
 		msleep(1);
-		temp = inb_p(SMBHSTSTS);
-	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
+
+	while ((timeout++ < MAX_TIMEOUT) &&
+	       ((temp = inb_p(SMBHSTSTS)) & 0x01))
+		msleep(1);
 
 	/* If the SMBus is still busy, we give up */
 	if (timeout >= MAX_TIMEOUT) {
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
index 8fbbdb4..114634d 100644
--- a/drivers/i2c/busses/i2c-sibyte.c
+++ b/drivers/i2c/busses/i2c-sibyte.c
@@ -132,14 +132,14 @@
 /*
  * registering functions to load algorithms at runtime
  */
-int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
+static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
 {
 	struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
 
-	/* register new adapter to i2c module... */
+	/* Register new adapter to i2c module... */
 	i2c_adap->algo = &i2c_sibyte_algo;
 
-	/* Set the frequency to 100 kHz */
+	/* Set the requested frequency. */
 	csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
 	csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
 
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 26384da..c99ebea 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -327,6 +327,11 @@
 EXPORT_SYMBOL_GPL(i2c_unregister_device);
 
 
+static const struct i2c_device_id dummy_id[] = {
+	{ "dummy", 0 },
+	{ },
+};
+
 static int dummy_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id)
 {
@@ -342,13 +347,13 @@
 	.driver.name	= "dummy",
 	.probe		= dummy_probe,
 	.remove		= dummy_remove,
+	.id_table	= dummy_id,
 };
 
 /**
  * i2c_new_dummy - return a new i2c device bound to a dummy driver
  * @adapter: the adapter managing the device
  * @address: seven bit address to be used
- * @type: optional label used for i2c_client.name
  * Context: can sleep
  *
  * This returns an I2C client bound to the "dummy" driver, intended for use
@@ -364,15 +369,12 @@
  * i2c_unregister_device(); or NULL to indicate an error.
  */
 struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type)
+i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
 {
 	struct i2c_board_info info = {
-		.driver_name	= "dummy",
-		.addr		= address,
+		I2C_BOARD_INFO("dummy", address),
 	};
 
-	if (type)
-		strlcpy(info.type, type, sizeof info.type);
 	return i2c_new_device(adapter, &info);
 }
 EXPORT_SYMBOL_GPL(i2c_new_dummy);
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index f702f91..b4f3aef 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -1,8 +1,6 @@
 #
 # IDE ATA ATAPI Block device driver configuration
 #
-# Andre Hedrick <andre@linux-ide.org>
-#
 
 # Select HAVE_IDE if IDE is supported
 config HAVE_IDE
@@ -335,7 +333,7 @@
 	  This driver will work automatically in PCI based systems (most new
 	  systems have PCI slots). But if your system uses VESA local bus
 	  (VLB) instead of PCI, you must also supply a kernel boot parameter
-	  to enable the CMD640 bugfix/support: "ide0=cmd640_vlb". (Try "man
+	  to enable the CMD640 bugfix/support: "cmd640.probe_vlb". (Try "man
 	  bootparam" or see the documentation of your boot loader about how to
 	  pass options to the kernel.)
 
@@ -457,27 +455,11 @@
 	  onboard chipsets.  It also tests for Simplex mode and enables
 	  normal dual channel support.
 
-	  If you say Y here, you also need to say Y to "Use DMA by default
-	  when available", above.  Please read the comments at the top of
+	  Please read the comments at the top of
 	  <file:drivers/ide/pci/alim15x3.c>.
 
 	  If unsure, say N.
 
-config WDC_ALI15X3
-	bool "ALI M15x3 WDC support (DANGEROUS)"
-	depends on BLK_DEV_ALI15X3
-	---help---
-	  This allows for UltraDMA support for WDC drives that ignore CRC
-	  checking. You are a fool for enabling this option, but there have
-	  been requests. DO NOT COMPLAIN IF YOUR DRIVE HAS FS CORRUPTION, IF
-	  YOU ENABLE THIS! No one will listen, just laugh for ignoring this
-	  SERIOUS WARNING.
-
-	  Using this option can allow WDC drives to run at ATA-4/5 transfer
-	  rates with only an ATA-2 support structure.
-
-	  SAY N!
-
 config BLK_DEV_AMD74XX
 	tristate "AMD and nVidia IDE support"
 	depends on !ARM
@@ -520,9 +502,6 @@
 	  This driver adds detection and support for the CY82C693 chipset
 	  used on Digital's PC-Alpha 164SX boards.
 
-	  If you say Y here, you need to say Y to "Use DMA by default
-	  when available" as well.
-
 config BLK_DEV_CS5520
 	tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)"
 	depends on EXPERIMENTAL
@@ -613,13 +592,12 @@
 	  National SCx200 series of embedded x86 "Geode" systems.
 
 config BLK_DEV_PIIX
-	tristate "Intel PIIXn chipsets support"
+	tristate "Intel PIIX/ICH chipsets support"
 	select BLK_DEV_IDEDMA_PCI
 	help
-	  This driver adds explicit support for Intel PIIX and ICH chips
-	  and also for the Efar Victory66 (slc90e66) chip.  This allows
-	  the kernel to change PIO, DMA and UDMA speeds and to configure
-	  the chip to optimum performance.
+	  This driver adds explicit support for Intel PIIX and ICH chips.
+	  This allows the kernel to change PIO, DMA and UDMA speeds and to
+	  configure the chip to optimum performance.
 
 config BLK_DEV_IT8213
 	tristate "IT8213 IDE support"
@@ -657,11 +635,7 @@
 	  happen if the BIOS revisions of all installed cards (three-max) do
 	  not match, the driver attempts to do dynamic tuning of the chipset
 	  at boot-time for max-speed.  Ultra33 BIOS 1.25 or newer is required
-	  for more than one card. This card may require that you say Y to
-	  "Special UDMA Feature".
-
-	  If you say Y here, you need to say Y to "Use DMA by default when
-	  available" as well.
+	  for more than one card.
 
 	  Please read the comments at the top of
 	  <file:drivers/ide/pci/pdc202xx_old.c>.
@@ -710,9 +684,6 @@
 	  ATA100: SiS635, SiS645, SiS650, SiS730, SiS735, SiS740,
 	  SiS745, SiS750
 
-	  If you say Y here, you need to say Y to "Use DMA by default when
-	  available" as well.
-
 	  Please read the comments at the top of <file:drivers/ide/pci/sis5513.c>.
 
 config BLK_DEV_SL82C105
@@ -734,9 +705,6 @@
 	  and it will handle timing cycles.  Since this is an improved
 	  look-a-like to the PIIX4 it should be a nice addition.
 
-	  If you say Y here, you need to say Y to "Use DMA by default when
-	  available" as well.
-
 	  Please read the comments at the top of
 	  <file:drivers/ide/pci/slc90e66.c>.
 
@@ -888,17 +856,17 @@
 	bool "Amiga IDE Doubler support (EXPERIMENTAL)"
 	depends on BLK_DEV_GAYLE && EXPERIMENTAL
 	---help---
-	  This driver provides support for the so-called `IDE doublers' (made
+	  This feature provides support for the so-called `IDE doublers' (made
 	  by various manufacturers, e.g. Eyetech) that can be connected to
 	  the on-board IDE interface of some Amiga models. Using such an IDE
 	  doubler, you can connect up to four instead of two IDE devices to
 	  the Amiga's on-board IDE interface.
 
 	  Note that the normal Amiga Gayle IDE driver may not work correctly
-	  if you have an IDE doubler and don't enable this driver!
+	  if you have an IDE doubler and don't enable this feature!
 
-	  Say Y if you have an IDE doubler.  The driver is enabled at kernel
-	  runtime using the "ide=doubler" kernel boot parameter.
+	  Say Y if you have an IDE doubler.  The feature is enabled at kernel
+	  runtime using the "gayle.doubler" kernel boot parameter.
 
 config BLK_DEV_BUDDHA
 	tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 57d9a9a..0daf923 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -95,7 +95,7 @@
 	hwif->OUTB(drive->select.all, hwif->io_ports.device_addr);
 }
 
-void SELECT_MASK (ide_drive_t *drive, int mask)
+static void SELECT_MASK(ide_drive_t *drive, int mask)
 {
 	const struct ide_port_ops *port_ops = drive->hwif->port_ops;
 
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index 83555ca..9e449a0 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -61,7 +61,7 @@
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
 	if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
-		return outsw(data_adr, buf, (len + 1) / 2);
+		return outsw(data_addr, buf, (len + 1) / 2);
 
 	outsw_swapw(data_addr, buf, (len + 1) / 2);
 }
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index 712d17b..52fee3d 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -4,7 +4,7 @@
  *	Author:	Manish Lachwani, mlachwani@mvista.com
  * Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
  *	Author: Maciej W. Rozycki <macro@mips.com>
- * Copyright (c) 2006  Maciej W. Rozycki
+ * Copyright (c) 2006, 2008  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -70,8 +70,9 @@
 	ide_hwif_t *hwif;
 	u8 __iomem *base;
 	phys_t offset, size;
+	hw_regs_t hw;
 	int i;
-	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+	u8 idx[] = { 0xff, 0xff, 0xff, 0xff };
 
 	if (!SIBYTE_HAVE_IDE)
 		return -ENODEV;
@@ -112,14 +113,15 @@
 	hwif->host_flags = IDE_HFLAG_MMIO;
 	default_hwif_mmiops(hwif);
 
-	hwif->chipset = ide_generic;
-
 	for (i = 0; i <= 7; i++)
-		hwif->io_ports_array[i] =
+		hw.io_ports_array[i] =
 				(unsigned long)(base + ((0x1f0 + i) << 5));
-	hwif->io_ports.ctl_addr =
+	hw.io_ports.ctl_addr =
 				(unsigned long)(base + (0x3f6 << 5));
-	hwif->irq = K_INT_GB_IDE;
+	hw.irq = K_INT_GB_IDE;
+	hw.chipset = ide_generic;
+
+	ide_init_port_hw(hwif, &hw);
 
 	idx[0] = hwif->index;
 
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index c1922f9..f2129d5 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -39,6 +39,16 @@
 #include <asm/io.h>
 
 /*
+ * Allow UDMA on M1543C-E chipset for WDC disks that ignore CRC checking
+ * (this is DANGEROUS and could result in data corruption).
+ */
+static int wdc_udma;
+
+module_param(wdc_udma, bool, 0);
+MODULE_PARM_DESC(wdc_udma,
+		 "allow UDMA on M1543C-E chipset for WDC disks (DANGEROUS)");
+
+/*
  *	ALi devices are not plug in. Otherwise these static values would
  *	need to go. They ought to go away anyway
  */
@@ -76,11 +86,6 @@
 		a_clc = 0;
 	c_time = ide_pio_timings[pio].cycle_time;
 
-#if 0
-	if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16)
-		r_clc = 0;
-#endif
-
 	if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
 		r_clc = 1;
 	} else {
@@ -110,16 +115,6 @@
 	pci_write_config_byte(dev, port, s_clc);
 	pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
 	local_irq_restore(flags);
-
-	/*
-	 * setup   active  rec
-	 * { 70,   165,    365 },   PIO Mode 0
-	 * { 50,   125,    208 },   PIO Mode 1
-	 * { 30,   100,    110 },   PIO Mode 2
-	 * { 30,   80,     70  },   PIO Mode 3 with IORDY
-	 * { 25,   70,     25  },   PIO Mode 4 with IORDY  ns
-	 * { 20,   50,     30  }    PIO Mode 5 with IORDY (nonstandard)
-	 */
 }
 
 /**
@@ -131,9 +126,7 @@
  *	The actual rules for the ALi are:
  *		No UDMA on revisions <= 0x20
  *		Disk only for revisions < 0xC2
- *		Not WDC drives for revisions < 0xC2
- *
- *	FIXME: WDC ifdef needs to die
+ *		Not WDC drives on M1543C-E (?)
  */
 
 static u8 ali_udma_filter(ide_drive_t *drive)
@@ -141,10 +134,9 @@
 	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
 		if (drive->media != ide_disk)
 			return 0;
-#ifndef CONFIG_WDC_ALI15X3
-		if (chip_is_1543c_e && strstr(drive->id->model, "WDC "))
+		if (chip_is_1543c_e && strstr(drive->id->model, "WDC ") &&
+		    wdc_udma == 0)
 			return 0;
-#endif
 	}
 
 	return drive->hwif->ultra_mask;
@@ -537,17 +529,9 @@
  
 static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	static struct pci_device_id ati_rs100[] = {
-		{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
-		{ },
-	};
-
 	struct ide_port_info d = ali15x3_chipset;
 	u8 rev = dev->revision, idx = id->driver_data;
 
-	if (pci_dev_present(ati_rs100))
-		printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
-
 	/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
 	if (rev <= 0xC4)
 		d.host_flags |= IDE_HFLAG_NO_LBA48_DMA;
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 17669a4..992b1cf 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -119,6 +119,7 @@
 	.dma_timeout		= ide_dma_timeout,
 };
 
+/* FIXME: VDMA is disabled because it caused system hangs */
 #define DECLARE_CS_DEV(name_str)				\
 	{							\
 		.name		= name_str,			\
@@ -126,7 +127,6 @@
 		.dma_ops	= &cs5520_dma_ops,		\
 		.host_flags	= IDE_HFLAG_ISA_PORTS |		\
 				  IDE_HFLAG_CS5520 |		\
-				  IDE_HFLAG_VDMA |		\
 				  IDE_HFLAG_NO_ATAPI_DMA |	\
 				  IDE_HFLAG_ABUSE_SET_DMA_MODE, \
 		.pio_mask	= ATA_PIO4,			\
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index ed2ee4b..3f441fc 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -359,9 +359,10 @@
 	cq->sw_wptr++;
 }
 
-void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count)
+int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count)
 {
 	u32 ptr;
+	int flushed = 0;
 
 	PDBG("%s wq %p cq %p\n", __func__, wq, cq);
 
@@ -369,8 +370,11 @@
 	PDBG("%s rq_rptr %u rq_wptr %u skip count %u\n", __func__,
 	    wq->rq_rptr, wq->rq_wptr, count);
 	ptr = wq->rq_rptr + count;
-	while (ptr++ != wq->rq_wptr)
+	while (ptr++ != wq->rq_wptr) {
 		insert_recv_cqe(wq, cq);
+		flushed++;
+	}
+	return flushed;
 }
 
 static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq,
@@ -394,18 +398,21 @@
 	cq->sw_wptr++;
 }
 
-void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
+int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count)
 {
 	__u32 ptr;
+	int flushed = 0;
 	struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2);
 
 	ptr = wq->sq_rptr + count;
-	sqp += count;
+	sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
 	while (ptr != wq->sq_wptr) {
 		insert_sq_cqe(wq, cq, sqp);
-		sqp++;
 		ptr++;
+		sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
+		flushed++;
 	}
+	return flushed;
 }
 
 /*
@@ -581,7 +588,7 @@
  * caller aquires the ctrl_qp lock before the call
  */
 static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr,
-				      u32 len, void *data, int completion)
+				      u32 len, void *data)
 {
 	u32 i, nr_wqe, copy_len;
 	u8 *copy_data;
@@ -617,7 +624,7 @@
 		flag = 0;
 		if (i == (nr_wqe - 1)) {
 			/* last WQE */
-			flag = completion ? T3_COMPLETION_FLAG : 0;
+			flag = T3_COMPLETION_FLAG;
 			if (len % 32)
 				utx_len = len / 32 + 1;
 			else
@@ -676,21 +683,20 @@
 	return 0;
 }
 
-/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl, and pbl_size
- * OUT: stag index, actual pbl_size, pbl_addr allocated.
+/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl_size and pbl_addr
+ * OUT: stag index
  * TBD: shared memory region support
  */
 static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
 			 u32 *stag, u8 stag_state, u32 pdid,
 			 enum tpt_mem_type type, enum tpt_mem_perm perm,
-			 u32 zbva, u64 to, u32 len, u8 page_size, __be64 *pbl,
-			 u32 *pbl_size, u32 *pbl_addr)
+			 u32 zbva, u64 to, u32 len, u8 page_size,
+			 u32 pbl_size, u32 pbl_addr)
 {
 	int err;
 	struct tpt_entry tpt;
 	u32 stag_idx;
 	u32 wptr;
-	int rereg = (*stag != T3_STAG_UNSET);
 
 	stag_state = stag_state > 0;
 	stag_idx = (*stag) >> 8;
@@ -704,30 +710,8 @@
 	PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n",
 	     __func__, stag_state, type, pdid, stag_idx);
 
-	if (reset_tpt_entry)
-		cxio_hal_pblpool_free(rdev_p, *pbl_addr, *pbl_size << 3);
-	else if (!rereg) {
-		*pbl_addr = cxio_hal_pblpool_alloc(rdev_p, *pbl_size << 3);
-		if (!*pbl_addr) {
-			return -ENOMEM;
-		}
-	}
-
 	mutex_lock(&rdev_p->ctrl_qp.lock);
 
-	/* write PBL first if any - update pbl only if pbl list exist */
-	if (pbl) {
-
-		PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n",
-		     __func__, *pbl_addr, rdev_p->rnic_info.pbl_base,
-		     *pbl_size);
-		err = cxio_hal_ctrl_qp_write_mem(rdev_p,
-				(*pbl_addr >> 5),
-				(*pbl_size << 3), pbl, 0);
-		if (err)
-			goto ret;
-	}
-
 	/* write TPT entry */
 	if (reset_tpt_entry)
 		memset(&tpt, 0, sizeof(tpt));
@@ -742,23 +726,23 @@
 				V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) |
 				V_TPT_PAGE_SIZE(page_size));
 		tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 :
-				    cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, *pbl_addr)>>3));
+				    cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3));
 		tpt.len = cpu_to_be32(len);
 		tpt.va_hi = cpu_to_be32((u32) (to >> 32));
 		tpt.va_low_or_fbo = cpu_to_be32((u32) (to & 0xFFFFFFFFULL));
 		tpt.rsvd_bind_cnt_or_pstag = 0;
 		tpt.rsvd_pbl_size = reset_tpt_entry ? 0 :
-				  cpu_to_be32(V_TPT_PBL_SIZE((*pbl_size) >> 2));
+				  cpu_to_be32(V_TPT_PBL_SIZE(pbl_size >> 2));
 	}
 	err = cxio_hal_ctrl_qp_write_mem(rdev_p,
 				       stag_idx +
 				       (rdev_p->rnic_info.tpt_base >> 5),
-				       sizeof(tpt), &tpt, 1);
+				       sizeof(tpt), &tpt);
 
 	/* release the stag index to free pool */
 	if (reset_tpt_entry)
 		cxio_hal_put_stag(rdev_p->rscp, stag_idx);
-ret:
+
 	wptr = rdev_p->ctrl_qp.wptr;
 	mutex_unlock(&rdev_p->ctrl_qp.lock);
 	if (!err)
@@ -769,44 +753,67 @@
 	return err;
 }
 
+int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl,
+		   u32 pbl_addr, u32 pbl_size)
+{
+	u32 wptr;
+	int err;
+
+	PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n",
+	     __func__, pbl_addr, rdev_p->rnic_info.pbl_base,
+	     pbl_size);
+
+	mutex_lock(&rdev_p->ctrl_qp.lock);
+	err = cxio_hal_ctrl_qp_write_mem(rdev_p, pbl_addr >> 5, pbl_size << 3,
+					 pbl);
+	wptr = rdev_p->ctrl_qp.wptr;
+	mutex_unlock(&rdev_p->ctrl_qp.lock);
+	if (err)
+		return err;
+
+	if (wait_event_interruptible(rdev_p->ctrl_qp.waitq,
+				     SEQ32_GE(rdev_p->ctrl_qp.rptr,
+					      wptr)))
+		return -ERESTARTSYS;
+
+	return 0;
+}
+
 int cxio_register_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid,
 			   enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-			   u8 page_size, __be64 *pbl, u32 *pbl_size,
-			   u32 *pbl_addr)
+			   u8 page_size, u32 pbl_size, u32 pbl_addr)
 {
 	*stag = T3_STAG_UNSET;
 	return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm,
-			     zbva, to, len, page_size, pbl, pbl_size, pbl_addr);
+			     zbva, to, len, page_size, pbl_size, pbl_addr);
 }
 
 int cxio_reregister_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid,
 			   enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-			   u8 page_size, __be64 *pbl, u32 *pbl_size,
-			   u32 *pbl_addr)
+			   u8 page_size, u32 pbl_size, u32 pbl_addr)
 {
 	return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm,
-			     zbva, to, len, page_size, pbl, pbl_size, pbl_addr);
+			     zbva, to, len, page_size, pbl_size, pbl_addr);
 }
 
 int cxio_dereg_mem(struct cxio_rdev *rdev_p, u32 stag, u32 pbl_size,
 		   u32 pbl_addr)
 {
-	return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL,
-			     &pbl_size, &pbl_addr);
+	return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0,
+			     pbl_size, pbl_addr);
 }
 
 int cxio_allocate_window(struct cxio_rdev *rdev_p, u32 * stag, u32 pdid)
 {
-	u32 pbl_size = 0;
 	*stag = T3_STAG_UNSET;
 	return __cxio_tpt_op(rdev_p, 0, stag, 0, pdid, TPT_MW, 0, 0, 0ULL, 0, 0,
-			     NULL, &pbl_size, NULL);
+			     0, 0);
 }
 
 int cxio_deallocate_window(struct cxio_rdev *rdev_p, u32 stag)
 {
-	return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL,
-			     NULL, NULL);
+	return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0,
+			     0, 0);
 }
 
 int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 2bcff7f..6e128f6 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -154,14 +154,14 @@
 int cxio_destroy_qp(struct cxio_rdev *rdev, struct t3_wq *wq,
 		    struct cxio_ucontext *uctx);
 int cxio_peek_cq(struct t3_wq *wr, struct t3_cq *cq, int opcode);
+int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl,
+		   u32 pbl_addr, u32 pbl_size);
 int cxio_register_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
 			   enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-			   u8 page_size, __be64 *pbl, u32 *pbl_size,
-			   u32 *pbl_addr);
+			   u8 page_size, u32 pbl_size, u32 pbl_addr);
 int cxio_reregister_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid,
 			   enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len,
-			   u8 page_size, __be64 *pbl, u32 *pbl_size,
-			   u32 *pbl_addr);
+			   u8 page_size, u32 pbl_size, u32 pbl_addr);
 int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size,
 		   u32 pbl_addr);
 int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid);
@@ -173,8 +173,8 @@
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid);
 int __init cxio_hal_init(void);
 void __exit cxio_hal_exit(void);
-void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count);
-void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count);
+int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count);
+int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count);
 void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
 void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
 void cxio_flush_hw_cq(struct t3_cq *cq);
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c
index 45ed4f2..bd233c0 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_resource.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c
@@ -250,7 +250,6 @@
  */
 
 #define MIN_PBL_SHIFT 8			/* 256B == min PBL size (32 entries) */
-#define PBL_CHUNK 2*1024*1024
 
 u32 cxio_hal_pblpool_alloc(struct cxio_rdev *rdev_p, int size)
 {
@@ -267,14 +266,35 @@
 
 int cxio_hal_pblpool_create(struct cxio_rdev *rdev_p)
 {
-	unsigned long i;
+	unsigned pbl_start, pbl_chunk;
+
 	rdev_p->pbl_pool = gen_pool_create(MIN_PBL_SHIFT, -1);
-	if (rdev_p->pbl_pool)
-		for (i = rdev_p->rnic_info.pbl_base;
-		     i <= rdev_p->rnic_info.pbl_top - PBL_CHUNK + 1;
-		     i += PBL_CHUNK)
-			gen_pool_add(rdev_p->pbl_pool, i, PBL_CHUNK, -1);
-	return rdev_p->pbl_pool ? 0 : -ENOMEM;
+	if (!rdev_p->pbl_pool)
+		return -ENOMEM;
+
+	pbl_start = rdev_p->rnic_info.pbl_base;
+	pbl_chunk = rdev_p->rnic_info.pbl_top - pbl_start + 1;
+
+	while (pbl_start < rdev_p->rnic_info.pbl_top) {
+		pbl_chunk = min(rdev_p->rnic_info.pbl_top - pbl_start + 1,
+				pbl_chunk);
+		if (gen_pool_add(rdev_p->pbl_pool, pbl_start, pbl_chunk, -1)) {
+			PDBG("%s failed to add PBL chunk (%x/%x)\n",
+			     __func__, pbl_start, pbl_chunk);
+			if (pbl_chunk <= 1024 << MIN_PBL_SHIFT) {
+				printk(KERN_WARNING MOD "%s: Failed to add all PBL chunks (%x/%x)\n",
+				       __func__, pbl_start, rdev_p->rnic_info.pbl_top - pbl_start);
+				return 0;
+			}
+			pbl_chunk >>= 1;
+		} else {
+			PDBG("%s added PBL chunk (%x/%x)\n",
+			     __func__, pbl_start, pbl_chunk);
+			pbl_start += pbl_chunk;
+		}
+	}
+
+	return 0;
 }
 
 void cxio_hal_pblpool_destroy(struct cxio_rdev *rdev_p)
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index d44a6df..c325c44 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -67,10 +67,10 @@
 module_param(peer2peer, int, 0644);
 MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)");
 
-static int ep_timeout_secs = 10;
+static int ep_timeout_secs = 60;
 module_param(ep_timeout_secs, int, 0644);
 MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout "
-				   "in seconds (default=10)");
+				   "in seconds (default=60)");
 
 static int mpa_rev = 1;
 module_param(mpa_rev, int, 0644);
@@ -1650,8 +1650,8 @@
 		release = 1;
 		break;
 	case ABORTING:
-		break;
 	case DEAD:
+		break;
 	default:
 		BUG_ON(1);
 		break;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c
index 58c3d61..ec49a5c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_mem.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c
@@ -35,17 +35,26 @@
 #include <rdma/ib_verbs.h>
 
 #include "cxio_hal.h"
+#include "cxio_resource.h"
 #include "iwch.h"
 #include "iwch_provider.h"
 
-int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
-					struct iwch_mr *mhp,
-					int shift,
-					__be64 *page_list)
+static void iwch_finish_mem_reg(struct iwch_mr *mhp, u32 stag)
 {
-	u32 stag;
 	u32 mmid;
 
+	mhp->attr.state = 1;
+	mhp->attr.stag = stag;
+	mmid = stag >> 8;
+	mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
+	insert_handle(mhp->rhp, &mhp->rhp->mmidr, mhp, mmid);
+	PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp);
+}
+
+int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
+		      struct iwch_mr *mhp, int shift)
+{
+	u32 stag;
 
 	if (cxio_register_phys_mem(&rhp->rdev,
 				   &stag, mhp->attr.pdid,
@@ -53,28 +62,21 @@
 				   mhp->attr.zbva,
 				   mhp->attr.va_fbo,
 				   mhp->attr.len,
-				   shift-12,
-				   page_list,
-				   &mhp->attr.pbl_size, &mhp->attr.pbl_addr))
+				   shift - 12,
+				   mhp->attr.pbl_size, mhp->attr.pbl_addr))
 		return -ENOMEM;
-	mhp->attr.state = 1;
-	mhp->attr.stag = stag;
-	mmid = stag >> 8;
-	mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
-	insert_handle(rhp, &rhp->mmidr, mhp, mmid);
-	PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp);
+
+	iwch_finish_mem_reg(mhp, stag);
+
 	return 0;
 }
 
 int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
 					struct iwch_mr *mhp,
 					int shift,
-					__be64 *page_list,
 					int npages)
 {
 	u32 stag;
-	u32 mmid;
-
 
 	/* We could support this... */
 	if (npages > mhp->attr.pbl_size)
@@ -87,19 +89,40 @@
 				   mhp->attr.zbva,
 				   mhp->attr.va_fbo,
 				   mhp->attr.len,
-				   shift-12,
-				   page_list,
-				   &mhp->attr.pbl_size, &mhp->attr.pbl_addr))
+				   shift - 12,
+				   mhp->attr.pbl_size, mhp->attr.pbl_addr))
 		return -ENOMEM;
-	mhp->attr.state = 1;
-	mhp->attr.stag = stag;
-	mmid = stag >> 8;
-	mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
-	insert_handle(rhp, &rhp->mmidr, mhp, mmid);
-	PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp);
+
+	iwch_finish_mem_reg(mhp, stag);
+
 	return 0;
 }
 
+int iwch_alloc_pbl(struct iwch_mr *mhp, int npages)
+{
+	mhp->attr.pbl_addr = cxio_hal_pblpool_alloc(&mhp->rhp->rdev,
+						    npages << 3);
+
+	if (!mhp->attr.pbl_addr)
+		return -ENOMEM;
+
+	mhp->attr.pbl_size = npages;
+
+	return 0;
+}
+
+void iwch_free_pbl(struct iwch_mr *mhp)
+{
+	cxio_hal_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
+			      mhp->attr.pbl_size << 3);
+}
+
+int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset)
+{
+	return cxio_write_pbl(&mhp->rhp->rdev, pages,
+			      mhp->attr.pbl_addr + (offset << 3), npages);
+}
+
 int build_phys_page_list(struct ib_phys_buf *buffer_list,
 					int num_phys_buf,
 					u64 *iova_start,
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index d07d3a3..8934178 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -442,6 +442,7 @@
 	mmid = mhp->attr.stag >> 8;
 	cxio_dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
 		       mhp->attr.pbl_addr);
+	iwch_free_pbl(mhp);
 	remove_handle(rhp, &rhp->mmidr, mmid);
 	if (mhp->kva)
 		kfree((void *) (unsigned long) mhp->kva);
@@ -475,6 +476,8 @@
 	if (!mhp)
 		return ERR_PTR(-ENOMEM);
 
+	mhp->rhp = rhp;
+
 	/* First check that we have enough alignment */
 	if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) {
 		ret = -EINVAL;
@@ -492,7 +495,17 @@
 	if (ret)
 		goto err;
 
-	mhp->rhp = rhp;
+	ret = iwch_alloc_pbl(mhp, npages);
+	if (ret) {
+		kfree(page_list);
+		goto err_pbl;
+	}
+
+	ret = iwch_write_pbl(mhp, page_list, npages, 0);
+	kfree(page_list);
+	if (ret)
+		goto err_pbl;
+
 	mhp->attr.pdid = php->pdid;
 	mhp->attr.zbva = 0;
 
@@ -502,12 +515,15 @@
 
 	mhp->attr.len = (u32) total_size;
 	mhp->attr.pbl_size = npages;
-	ret = iwch_register_mem(rhp, php, mhp, shift, page_list);
-	kfree(page_list);
-	if (ret) {
-		goto err;
-	}
+	ret = iwch_register_mem(rhp, php, mhp, shift);
+	if (ret)
+		goto err_pbl;
+
 	return &mhp->ibmr;
+
+err_pbl:
+	iwch_free_pbl(mhp);
+
 err:
 	kfree(mhp);
 	return ERR_PTR(ret);
@@ -560,7 +576,7 @@
 			return ret;
 	}
 
-	ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages);
+	ret = iwch_reregister_mem(rhp, php, &mh, shift, npages);
 	kfree(page_list);
 	if (ret) {
 		return ret;
@@ -602,6 +618,8 @@
 	if (!mhp)
 		return ERR_PTR(-ENOMEM);
 
+	mhp->rhp = rhp;
+
 	mhp->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0);
 	if (IS_ERR(mhp->umem)) {
 		err = PTR_ERR(mhp->umem);
@@ -615,10 +633,14 @@
 	list_for_each_entry(chunk, &mhp->umem->chunk_list, list)
 		n += chunk->nents;
 
-	pages = kmalloc(n * sizeof(u64), GFP_KERNEL);
+	err = iwch_alloc_pbl(mhp, n);
+	if (err)
+		goto err;
+
+	pages = (__be64 *) __get_free_page(GFP_KERNEL);
 	if (!pages) {
 		err = -ENOMEM;
-		goto err;
+		goto err_pbl;
 	}
 
 	i = n = 0;
@@ -630,25 +652,38 @@
 				pages[i++] = cpu_to_be64(sg_dma_address(
 					&chunk->page_list[j]) +
 					mhp->umem->page_size * k);
+				if (i == PAGE_SIZE / sizeof *pages) {
+					err = iwch_write_pbl(mhp, pages, i, n);
+					if (err)
+						goto pbl_done;
+					n += i;
+					i = 0;
+				}
 			}
 		}
 
-	mhp->rhp = rhp;
+	if (i)
+		err = iwch_write_pbl(mhp, pages, i, n);
+
+pbl_done:
+	free_page((unsigned long) pages);
+	if (err)
+		goto err_pbl;
+
 	mhp->attr.pdid = php->pdid;
 	mhp->attr.zbva = 0;
 	mhp->attr.perms = iwch_ib_to_tpt_access(acc);
 	mhp->attr.va_fbo = virt;
 	mhp->attr.page_size = shift - 12;
 	mhp->attr.len = (u32) length;
-	mhp->attr.pbl_size = i;
-	err = iwch_register_mem(rhp, php, mhp, shift, pages);
-	kfree(pages);
+
+	err = iwch_register_mem(rhp, php, mhp, shift);
 	if (err)
-		goto err;
+		goto err_pbl;
 
 	if (udata && !t3a_device(rhp)) {
 		uresp.pbl_addr = (mhp->attr.pbl_addr -
-	                         rhp->rdev.rnic_info.pbl_base) >> 3;
+				 rhp->rdev.rnic_info.pbl_base) >> 3;
 		PDBG("%s user resp pbl_addr 0x%x\n", __func__,
 		     uresp.pbl_addr);
 
@@ -661,6 +696,9 @@
 
 	return &mhp->ibmr;
 
+err_pbl:
+	iwch_free_pbl(mhp);
+
 err:
 	ib_umem_release(mhp->umem);
 	kfree(mhp);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h
index db5100d..836163f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h
@@ -340,14 +340,14 @@
 int iwch_resume_qps(struct iwch_cq *chp);
 void stop_read_rep_timer(struct iwch_qp *qhp);
 int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php,
-					struct iwch_mr *mhp,
-					int shift,
-					__be64 *page_list);
+		      struct iwch_mr *mhp, int shift);
 int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php,
 					struct iwch_mr *mhp,
 					int shift,
-					__be64 *page_list,
 					int npages);
+int iwch_alloc_pbl(struct iwch_mr *mhp, int npages);
+void iwch_free_pbl(struct iwch_mr *mhp);
+int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset);
 int build_phys_page_list(struct ib_phys_buf *buffer_list,
 					int num_phys_buf,
 					u64 *iova_start,
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 9b4be88..79dbe5b 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -655,6 +655,7 @@
 {
 	struct iwch_cq *rchp, *schp;
 	int count;
+	int flushed;
 
 	rchp = get_chp(qhp->rhp, qhp->attr.rcq);
 	schp = get_chp(qhp->rhp, qhp->attr.scq);
@@ -669,20 +670,22 @@
 	spin_lock(&qhp->lock);
 	cxio_flush_hw_cq(&rchp->cq);
 	cxio_count_rcqes(&rchp->cq, &qhp->wq, &count);
-	cxio_flush_rq(&qhp->wq, &rchp->cq, count);
+	flushed = cxio_flush_rq(&qhp->wq, &rchp->cq, count);
 	spin_unlock(&qhp->lock);
 	spin_unlock_irqrestore(&rchp->lock, *flag);
-	(*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
+	if (flushed)
+		(*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context);
 
 	/* locking heirarchy: cq lock first, then qp lock. */
 	spin_lock_irqsave(&schp->lock, *flag);
 	spin_lock(&qhp->lock);
 	cxio_flush_hw_cq(&schp->cq);
 	cxio_count_scqes(&schp->cq, &qhp->wq, &count);
-	cxio_flush_sq(&qhp->wq, &schp->cq, count);
+	flushed = cxio_flush_sq(&qhp->wq, &schp->cq, count);
 	spin_unlock(&qhp->lock);
 	spin_unlock_irqrestore(&schp->lock, *flag);
-	(*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context);
+	if (flushed)
+		(*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context);
 
 	/* deref */
 	if (atomic_dec_and_test(&qhp->refcnt))
@@ -880,7 +883,6 @@
 				ep = qhp->ep;
 				get_ep(&ep->com);
 			}
-			flush_qp(qhp, &flag);
 			break;
 		case IWCH_QP_STATE_TERMINATE:
 			qhp->attr.state = IWCH_QP_STATE_TERMINATE;
@@ -911,6 +913,7 @@
 		}
 		switch (attrs->next_state) {
 			case IWCH_QP_STATE_IDLE:
+				flush_qp(qhp, &flag);
 				qhp->attr.state = IWCH_QP_STATE_IDLE;
 				qhp->attr.llp_stream_handle = NULL;
 				put_ep(&qhp->ep->com);
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 00bab60..1e9e99a 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -192,6 +192,8 @@
 	int mtu_shift;
 	u32 message_count;
 	u32 packet_count;
+	atomic_t nr_events; /* events seen */
+	wait_queue_head_t wait_completion;
 };
 
 #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 2515cbd..bc3b37d 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -101,7 +101,6 @@
 	props->max_ee          = limit_uint(rblock->max_rd_ee_context);
 	props->max_rdd         = limit_uint(rblock->max_rd_domain);
 	props->max_fmr         = limit_uint(rblock->max_mr);
-	props->local_ca_ack_delay  = limit_uint(rblock->local_ca_ack_delay);
 	props->max_qp_rd_atom  = limit_uint(rblock->max_rr_qp);
 	props->max_ee_rd_atom  = limit_uint(rblock->max_rr_ee_context);
 	props->max_res_rd_atom = limit_uint(rblock->max_rr_hca);
@@ -115,7 +114,7 @@
 	}
 
 	props->max_pkeys           = 16;
-	props->local_ca_ack_delay  = limit_uint(rblock->local_ca_ack_delay);
+	props->local_ca_ack_delay  = min_t(u8, rblock->local_ca_ack_delay, 255);
 	props->max_raw_ipv6_qp     = limit_uint(rblock->max_raw_ipv6_qp);
 	props->max_raw_ethy_qp     = limit_uint(rblock->max_raw_ethy_qp);
 	props->max_mcast_grp       = limit_uint(rblock->max_mcast_grp);
@@ -136,7 +135,7 @@
 	return ret;
 }
 
-static int map_mtu(struct ehca_shca *shca, u32 fw_mtu)
+static enum ib_mtu map_mtu(struct ehca_shca *shca, u32 fw_mtu)
 {
 	switch (fw_mtu) {
 	case 0x1:
@@ -156,7 +155,7 @@
 	}
 }
 
-static int map_number_of_vls(struct ehca_shca *shca, u32 vl_cap)
+static u8 map_number_of_vls(struct ehca_shca *shca, u32 vl_cap)
 {
 	switch (vl_cap) {
 	case 0x1:
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index ca5eb0c..ce1ab05 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -204,6 +204,8 @@
 
 	read_lock(&ehca_qp_idr_lock);
 	qp = idr_find(&ehca_qp_idr, token);
+	if (qp)
+		atomic_inc(&qp->nr_events);
 	read_unlock(&ehca_qp_idr_lock);
 
 	if (!qp)
@@ -223,6 +225,8 @@
 	if (fatal && qp->ext_type == EQPT_SRQBASE)
 		dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED);
 
+	if (atomic_dec_and_test(&qp->nr_events))
+		wake_up(&qp->wait_completion);
 	return;
 }
 
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 18fba92..3f59587 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -566,6 +566,8 @@
 		return ERR_PTR(-ENOMEM);
 	}
 
+	atomic_set(&my_qp->nr_events, 0);
+	init_waitqueue_head(&my_qp->wait_completion);
 	spin_lock_init(&my_qp->spinlock_s);
 	spin_lock_init(&my_qp->spinlock_r);
 	my_qp->qp_type = qp_type;
@@ -1934,6 +1936,9 @@
 	idr_remove(&ehca_qp_idr, my_qp->token);
 	write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
 
+	/* now wait until all pending events have completed */
+	wait_event(my_qp->wait_completion, !atomic_read(&my_qp->nr_events));
+
 	h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
 	if (h_ret != H_SUCCESS) {
 		ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li "
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index acf30c0..daad09a 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -1197,7 +1197,7 @@
 	}
 
 reloop:
-	for (last = 0, i = 1; !last; i++) {
+	for (last = 0, i = 1; !last; i += !last) {
 		hdr = dd->ipath_f_get_msgheader(dd, rhf_addr);
 		eflags = ipath_hdrget_err_flags(rhf_addr);
 		etype = ipath_hdrget_rcv_type(rhf_addr);
@@ -1428,6 +1428,40 @@
 	spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
 }
 
+/*
+ * used to force update of pioavailshadow if we can't get a pio buffer.
+ * Needed primarily due to exitting freeze mode after recovering
+ * from errors.  Done lazily, because it's safer (known to not
+ * be writing pio buffers).
+ */
+static void ipath_reset_availshadow(struct ipath_devdata *dd)
+{
+	int i, im;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ipath_pioavail_lock, flags);
+	for (i = 0; i < dd->ipath_pioavregs; i++) {
+		u64 val, oldval;
+		/* deal with 6110 chip bug on high register #s */
+		im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ?
+			i ^ 1 : i;
+		val = le64_to_cpu(dd->ipath_pioavailregs_dma[im]);
+		/*
+		 * busy out the buffers not in the kernel avail list,
+		 * without changing the generation bits.
+		 */
+		oldval = dd->ipath_pioavailshadow[i];
+		dd->ipath_pioavailshadow[i] = val |
+			((~dd->ipath_pioavailkernel[i] <<
+			INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT) &
+			0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */
+		if (oldval != dd->ipath_pioavailshadow[i])
+			ipath_dbg("shadow[%d] was %Lx, now %lx\n",
+				i, oldval, dd->ipath_pioavailshadow[i]);
+	}
+	spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
+}
+
 /**
  * ipath_setrcvhdrsize - set the receive header size
  * @dd: the infinipath device
@@ -1482,9 +1516,12 @@
 	 */
 	ipath_stats.sps_nopiobufs++;
 	if (!(++dd->ipath_consec_nopiobuf % 100000)) {
-		ipath_dbg("%u pio sends with no bufavail; dmacopy: "
-			"%llx %llx %llx %llx; shadow:  %lx %lx %lx %lx\n",
+		ipath_force_pio_avail_update(dd); /* at start */
+		ipath_dbg("%u tries no piobufavail ts%lx; dmacopy: "
+			"%llx %llx %llx %llx\n"
+			"ipath  shadow:  %lx %lx %lx %lx\n",
 			dd->ipath_consec_nopiobuf,
+			(unsigned long)get_cycles(),
 			(unsigned long long) le64_to_cpu(dma[0]),
 			(unsigned long long) le64_to_cpu(dma[1]),
 			(unsigned long long) le64_to_cpu(dma[2]),
@@ -1496,14 +1533,17 @@
 		 */
 		if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) >
 		    (sizeof(shadow[0]) * 4 * 4))
-			ipath_dbg("2nd group: dmacopy: %llx %llx "
-				  "%llx %llx; shadow: %lx %lx %lx %lx\n",
+			ipath_dbg("2nd group: dmacopy: "
+				  "%llx %llx %llx %llx\n"
+				  "ipath  shadow:  %lx %lx %lx %lx\n",
 				  (unsigned long long)le64_to_cpu(dma[4]),
 				  (unsigned long long)le64_to_cpu(dma[5]),
 				  (unsigned long long)le64_to_cpu(dma[6]),
 				  (unsigned long long)le64_to_cpu(dma[7]),
-				  shadow[4], shadow[5], shadow[6],
-				  shadow[7]);
+				  shadow[4], shadow[5], shadow[6], shadow[7]);
+
+		/* at end, so update likely happened */
+		ipath_reset_availshadow(dd);
 	}
 }
 
@@ -1652,19 +1692,46 @@
 			      unsigned len, int avail)
 {
 	unsigned long flags;
-	unsigned end;
+	unsigned end, cnt = 0, next;
 
 	/* There are two bits per send buffer (busy and generation) */
 	start *= 2;
-	len *= 2;
-	end = start + len;
+	end = start + len * 2;
 
-	/* Set or clear the generation bits. */
 	spin_lock_irqsave(&ipath_pioavail_lock, flags);
+	/* Set or clear the busy bit in the shadow. */
 	while (start < end) {
 		if (avail) {
-			__clear_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT,
-				dd->ipath_pioavailshadow);
+			unsigned long dma;
+			int i, im;
+			/*
+			 * the BUSY bit will never be set, because we disarm
+			 * the user buffers before we hand them back to the
+			 * kernel.  We do have to make sure the generation
+			 * bit is set correctly in shadow, since it could
+			 * have changed many times while allocated to user.
+			 * We can't use the bitmap functions on the full
+			 * dma array because it is always little-endian, so
+			 * we have to flip to host-order first.
+			 * BITS_PER_LONG is slightly wrong, since it's
+			 * always 64 bits per register in chip...
+			 * We only work on 64 bit kernels, so that's OK.
+			 */
+			/* deal with 6110 chip bug on high register #s */
+			i = start / BITS_PER_LONG;
+			im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ?
+				i ^ 1 : i;
+			__clear_bit(INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT
+				+ start, dd->ipath_pioavailshadow);
+			dma = (unsigned long) le64_to_cpu(
+				dd->ipath_pioavailregs_dma[im]);
+			if (test_bit((INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT
+				+ start) % BITS_PER_LONG, &dma))
+				__set_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT
+					+ start, dd->ipath_pioavailshadow);
+			else
+				__clear_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT
+					+ start, dd->ipath_pioavailshadow);
 			__set_bit(start, dd->ipath_pioavailkernel);
 		} else {
 			__set_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT,
@@ -1673,7 +1740,44 @@
 		}
 		start += 2;
 	}
+
+	if (dd->ipath_pioupd_thresh) {
+		end = 2 * (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k);
+		next = find_first_bit(dd->ipath_pioavailkernel, end);
+		while (next < end) {
+			cnt++;
+			next = find_next_bit(dd->ipath_pioavailkernel, end,
+					next + 1);
+		}
+	}
 	spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
+
+	/*
+	 * When moving buffers from kernel to user, if number assigned to
+	 * the user is less than the pio update threshold, and threshold
+	 * is supported (cnt was computed > 0), drop the update threshold
+	 * so we update at least once per allocated number of buffers.
+	 * In any case, if the kernel buffers are less than the threshold,
+	 * drop the threshold.  We don't bother increasing it, having once
+	 * decreased it, since it would typically just cycle back and forth.
+	 * If we don't decrease below buffers in use, we can wait a long
+	 * time for an update, until some other context uses PIO buffers.
+	 */
+	if (!avail && len < cnt)
+		cnt = len;
+	if (cnt < dd->ipath_pioupd_thresh) {
+		dd->ipath_pioupd_thresh = cnt;
+		ipath_dbg("Decreased pio update threshold to %u\n",
+			dd->ipath_pioupd_thresh);
+		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
+		dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK
+			<< INFINIPATH_S_UPDTHRESH_SHIFT);
+		dd->ipath_sendctrl |= dd->ipath_pioupd_thresh
+			<< INFINIPATH_S_UPDTHRESH_SHIFT;
+		ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
+			dd->ipath_sendctrl);
+		spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
+	}
 }
 
 /**
@@ -1790,12 +1894,12 @@
 	 */
 	if (dd->ipath_flags & IPATH_HAS_SEND_DMA) {
 		int skip_cancel;
-		u64 *statp = &dd->ipath_sdma_status;
+		unsigned long *statp = &dd->ipath_sdma_status;
 
 		spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
 		skip_cancel =
-			!test_bit(IPATH_SDMA_DISABLED, statp) &&
-			test_and_set_bit(IPATH_SDMA_ABORTING, statp);
+			test_and_set_bit(IPATH_SDMA_ABORTING, statp)
+			&& !test_bit(IPATH_SDMA_DISABLED, statp);
 		spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
 		if (skip_cancel)
 			goto bail;
@@ -1826,6 +1930,9 @@
 	ipath_disarm_piobufs(dd, 0,
 		dd->ipath_piobcnt2k + dd->ipath_piobcnt4k);
 
+	if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
+		set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
+
 	if (restore_sendctrl) {
 		/* else done by caller later if needed */
 		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
@@ -1845,7 +1952,6 @@
 		/* only wait so long for intr */
 		dd->ipath_sdma_abort_intr_timeout = jiffies + HZ;
 		dd->ipath_sdma_reset_wait = 200;
-		__set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
 		if (!test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status))
 			tasklet_hi_schedule(&dd->ipath_sdma_abort_task);
 		spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
@@ -2510,7 +2616,7 @@
 				ipath_dbg("unit %u port %d is in use "
 					  "(PID %u cmd %s), can't reset\n",
 					  unit, i,
-					  dd->ipath_pd[i]->port_pid,
+					  pid_nr(dd->ipath_pd[i]->port_pid),
 					  dd->ipath_pd[i]->port_comm);
 				ret = -EBUSY;
 				goto bail;
@@ -2548,19 +2654,21 @@
 static int ipath_signal_procs(struct ipath_devdata *dd, int sig)
 {
 	int i, sub, any = 0;
-	pid_t pid;
+	struct pid *pid;
 
 	if (!dd->ipath_pd)
 		return 0;
 	for (i = 1; i < dd->ipath_cfgports; i++) {
-		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt ||
-		    !dd->ipath_pd[i]->port_pid)
+		if (!dd->ipath_pd[i] || !dd->ipath_pd[i]->port_cnt)
 			continue;
 		pid = dd->ipath_pd[i]->port_pid;
+		if (!pid)
+			continue;
+
 		dev_info(&dd->pcidev->dev, "context %d in use "
 			  "(PID %u), sending signal %d\n",
-			  i, pid, sig);
-		kill_proc(pid, sig, 1);
+			  i, pid_nr(pid), sig);
+		kill_pid(pid, sig, 1);
 		any++;
 		for (sub = 0; sub < INFINIPATH_MAX_SUBPORT; sub++) {
 			pid = dd->ipath_pd[i]->port_subpid[sub];
@@ -2568,8 +2676,8 @@
 				continue;
 			dev_info(&dd->pcidev->dev, "sub-context "
 				"%d:%d in use (PID %u), sending "
-				"signal %d\n", i, sub, pid, sig);
-			kill_proc(pid, sig, 1);
+				"signal %d\n", i, sub, pid_nr(pid), sig);
+			kill_pid(pid, sig, 1);
 			any++;
 		}
 	}
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 8b17522..b472b15 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -173,47 +173,25 @@
 		(void *) dd->ipath_statusp -
 		(void *) dd->ipath_pioavailregs_dma;
 	if (!shared) {
-		kinfo->spi_piocnt = dd->ipath_pbufsport;
+		kinfo->spi_piocnt = pd->port_piocnt;
 		kinfo->spi_piobufbase = (u64) pd->port_piobufs;
 		kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
 			dd->ipath_ureg_align * pd->port_port;
 	} else if (master) {
-		kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) +
-				    (dd->ipath_pbufsport % subport_cnt);
+		kinfo->spi_piocnt = (pd->port_piocnt / subport_cnt) +
+				    (pd->port_piocnt % subport_cnt);
 		/* Master's PIO buffers are after all the slave's */
 		kinfo->spi_piobufbase = (u64) pd->port_piobufs +
 			dd->ipath_palign *
-			(dd->ipath_pbufsport - kinfo->spi_piocnt);
+			(pd->port_piocnt - kinfo->spi_piocnt);
 	} else {
 		unsigned slave = subport_fp(fp) - 1;
 
-		kinfo->spi_piocnt = dd->ipath_pbufsport / subport_cnt;
+		kinfo->spi_piocnt = pd->port_piocnt / subport_cnt;
 		kinfo->spi_piobufbase = (u64) pd->port_piobufs +
 			dd->ipath_palign * kinfo->spi_piocnt * slave;
 	}
 
-	/*
-	 * Set the PIO avail update threshold to no larger
-	 * than the number of buffers per process. Note that
-	 * we decrease it here, but won't ever increase it.
-	 */
-	if (dd->ipath_pioupd_thresh &&
-	    kinfo->spi_piocnt < dd->ipath_pioupd_thresh) {
-		unsigned long flags;
-
-		dd->ipath_pioupd_thresh = kinfo->spi_piocnt;
-		ipath_dbg("Decreased pio update threshold to %u\n",
-			dd->ipath_pioupd_thresh);
-		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
-		dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK
-			<< INFINIPATH_S_UPDTHRESH_SHIFT);
-		dd->ipath_sendctrl |= dd->ipath_pioupd_thresh
-			<< INFINIPATH_S_UPDTHRESH_SHIFT;
-		ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
-			dd->ipath_sendctrl);
-		spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
-	}
-
 	if (shared) {
 		kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase +
 			dd->ipath_ureg_align * pd->port_port;
@@ -577,7 +555,7 @@
 			p = dd->ipath_pageshadow[porttid + tid];
 			dd->ipath_pageshadow[porttid + tid] = NULL;
 			ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n",
-				   pd->port_pid, tid);
+				   pid_nr(pd->port_pid), tid);
 			dd->ipath_f_put_tid(dd, &tidbase[tid],
 					    RCVHQ_RCV_TYPE_EXPECTED,
 					    dd->ipath_tidinvalid);
@@ -1309,19 +1287,19 @@
 	ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port;
 	if (!pd->port_subport_cnt) {
 		/* port is not shared */
-		piocnt = dd->ipath_pbufsport;
+		piocnt = pd->port_piocnt;
 		piobufs = pd->port_piobufs;
 	} else if (!subport_fp(fp)) {
 		/* caller is the master */
-		piocnt = (dd->ipath_pbufsport / pd->port_subport_cnt) +
-			 (dd->ipath_pbufsport % pd->port_subport_cnt);
+		piocnt = (pd->port_piocnt / pd->port_subport_cnt) +
+			 (pd->port_piocnt % pd->port_subport_cnt);
 		piobufs = pd->port_piobufs +
-			dd->ipath_palign * (dd->ipath_pbufsport - piocnt);
+			dd->ipath_palign * (pd->port_piocnt - piocnt);
 	} else {
 		unsigned slave = subport_fp(fp) - 1;
 
 		/* caller is a slave */
-		piocnt = dd->ipath_pbufsport / pd->port_subport_cnt;
+		piocnt = pd->port_piocnt / pd->port_subport_cnt;
 		piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave;
 	}
 
@@ -1631,11 +1609,8 @@
 			   port);
 		pd->port_cnt = 1;
 		port_fp(fp) = pd;
-		pd->port_pid = current->pid;
+		pd->port_pid = get_pid(task_pid(current));
 		strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
-		ipath_chg_pioavailkernel(dd,
-			dd->ipath_pbufsport * (pd->port_port - 1),
-			dd->ipath_pbufsport, 0);
 		ipath_stats.sps_ports++;
 		ret = 0;
 	} else
@@ -1818,14 +1793,15 @@
 			}
 			port_fp(fp) = pd;
 			subport_fp(fp) = pd->port_cnt++;
-			pd->port_subpid[subport_fp(fp)] = current->pid;
+			pd->port_subpid[subport_fp(fp)] =
+				get_pid(task_pid(current));
 			tidcursor_fp(fp) = 0;
 			pd->active_slaves |= 1 << subport_fp(fp);
 			ipath_cdbg(PROC,
 				   "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
 				   current->comm, current->pid,
 				   subport_fp(fp),
-				   pd->port_comm, pd->port_pid,
+				   pd->port_comm, pid_nr(pd->port_pid),
 				   dd->ipath_unit, pd->port_port);
 			ret = 1;
 			goto done;
@@ -1938,11 +1914,25 @@
 
 	/* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */
 
+	/* some ports may get extra buffers, calculate that here */
+	if (pd->port_port <= dd->ipath_ports_extrabuf)
+		pd->port_piocnt = dd->ipath_pbufsport + 1;
+	else
+		pd->port_piocnt = dd->ipath_pbufsport;
+
 	/* for right now, kernel piobufs are at end, so port 1 is at 0 */
+	if (pd->port_port <= dd->ipath_ports_extrabuf)
+		pd->port_pio_base = (dd->ipath_pbufsport + 1)
+			* (pd->port_port - 1);
+	else
+		pd->port_pio_base = dd->ipath_ports_extrabuf +
+			dd->ipath_pbufsport * (pd->port_port - 1);
 	pd->port_piobufs = dd->ipath_piobufbase +
-		dd->ipath_pbufsport * (pd->port_port - 1) * dd->ipath_palign;
-	ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n",
-		   pd->port_port, pd->port_piobufs);
+		pd->port_pio_base * dd->ipath_palign;
+	ipath_cdbg(VERBOSE, "piobuf base for port %u is 0x%x, piocnt %u,"
+		" first pio %u\n", pd->port_port, pd->port_piobufs,
+		pd->port_piocnt, pd->port_pio_base);
+	ipath_chg_pioavailkernel(dd, pd->port_pio_base, pd->port_piocnt, 0);
 
 	/*
 	 * Now allocate the rcvhdr Q and eager TIDs; skip the TID
@@ -2077,7 +2067,8 @@
 		 * the slave(s) don't wait for receive data forever.
 		 */
 		pd->active_slaves &= ~(1 << fd->subport);
-		pd->port_subpid[fd->subport] = 0;
+		put_pid(pd->port_subpid[fd->subport]);
+		pd->port_subpid[fd->subport] = NULL;
 		mutex_unlock(&ipath_mutex);
 		goto bail;
 	}
@@ -2085,7 +2076,7 @@
 
 	if (pd->port_hdrqfull) {
 		ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors "
-			   "during run\n", pd->port_comm, pd->port_pid,
+			   "during run\n", pd->port_comm, pid_nr(pd->port_pid),
 			   pd->port_hdrqfull);
 		pd->port_hdrqfull = 0;
 	}
@@ -2107,7 +2098,6 @@
 	}
 
 	if (dd->ipath_kregbase) {
-		int i;
 		/* atomically clear receive enable port and intr avail. */
 		clear_bit(dd->ipath_r_portenable_shift + port,
 			  &dd->ipath_rcvctrl);
@@ -2136,9 +2126,9 @@
 		ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr,
 			pd->port_port, dd->ipath_dummy_hdrq_phys);
 
-		i = dd->ipath_pbufsport * (port - 1);
-		ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport);
-		ipath_chg_pioavailkernel(dd, i, dd->ipath_pbufsport, 1);
+		ipath_disarm_piobufs(dd, pd->port_pio_base, pd->port_piocnt);
+		ipath_chg_pioavailkernel(dd, pd->port_pio_base,
+			pd->port_piocnt, 1);
 
 		dd->ipath_f_clear_tids(dd, pd->port_port);
 
@@ -2146,11 +2136,12 @@
 			unlock_expected_tids(pd);
 		ipath_stats.sps_ports--;
 		ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
-			   pd->port_comm, pd->port_pid,
+			   pd->port_comm, pid_nr(pd->port_pid),
 			   dd->ipath_unit, port);
 	}
 
-	pd->port_pid = 0;
+	put_pid(pd->port_pid);
+	pd->port_pid = NULL;
 	dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */
 	mutex_unlock(&ipath_mutex);
 	ipath_free_pddata(dd, pd); /* after releasing the mutex */
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c
index e3ec0d1..8eee783 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba7220.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c
@@ -595,7 +595,7 @@
 
 	dev_info(&dd->pcidev->dev,
 		"Recovering from TXE PIO parity error\n");
-	ipath_disarm_senderrbufs(dd, 1);
+	ipath_disarm_senderrbufs(dd);
 }
 
 
@@ -675,10 +675,8 @@
 	ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control);
 	if ((ctrl & INFINIPATH_C_FREEZEMODE) && !ipath_diag_inuse) {
 		/*
-		 * Parity errors in send memory are recoverable,
-		 * just cancel the send (if indicated in * sendbuffererror),
-		 * count the occurrence, unfreeze (if no other handled
-		 * hardware error bits are set), and continue.
+		 * Parity errors in send memory are recoverable by h/w
+		 * just do housekeeping, exit freeze mode and continue.
 		 */
 		if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
 			       INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
@@ -687,13 +685,6 @@
 			hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF |
 				     INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC)
 				    << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT);
-			if (!hwerrs) {
-				/* else leave in freeze mode */
-				ipath_write_kreg(dd,
-						 dd->ipath_kregs->kr_control,
-						 dd->ipath_control);
-				goto bail;
-			}
 		}
 		if (hwerrs) {
 			/*
@@ -723,8 +714,8 @@
 			*dd->ipath_statusp |= IPATH_STATUS_HWERROR;
 			dd->ipath_flags &= ~IPATH_INITTED;
 		} else {
-			ipath_dbg("Clearing freezemode on ignored hardware "
-				  "error\n");
+			ipath_dbg("Clearing freezemode on ignored or "
+				"recovered hardware error\n");
 			ipath_clear_freeze(dd);
 		}
 	}
@@ -870,8 +861,9 @@
 			      "revision %u.%u!\n",
 			      dd->ipath_majrev, dd->ipath_minrev);
 		ret = 1;
-	} else if (dd->ipath_minrev == 1) {
-		/* Rev1 chips are prototype. Complain, but allow use */
+	} else if (dd->ipath_minrev == 1 &&
+		!(dd->ipath_flags & IPATH_INITTED)) {
+		/* Rev1 chips are prototype. Complain at init, but allow use */
 		ipath_dev_err(dd, "Unsupported hardware "
 			      "revision %u.%u, Contact support@qlogic.com\n",
 			      dd->ipath_majrev, dd->ipath_minrev);
@@ -1966,7 +1958,7 @@
 			 dd->ipath_rcvctrl);
 	dd->ipath_p0_rcvegrcnt = 2048; /* always */
 	if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
-		dd->ipath_pioreserved = 1; /* reserve a buffer */
+		dd->ipath_pioreserved = 3; /* kpiobufs used for PIO */
 }
 
 
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 27dd894..3e5baa4 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -41,7 +41,7 @@
 /*
  * min buffers we want to have per port, after driver
  */
-#define IPATH_MIN_USER_PORT_BUFCNT 8
+#define IPATH_MIN_USER_PORT_BUFCNT 7
 
 /*
  * Number of ports we are configured to use (to allow for more pio
@@ -54,13 +54,9 @@
 
 /*
  * Number of buffers reserved for driver (verbs and layered drivers.)
- * Reserved at end of buffer list.   Initialized based on
- * number of PIO buffers if not set via module interface.
+ * Initialized based on number of PIO buffers if not set via module interface.
  * The problem with this is that it's global, but we'll use different
- * numbers for different chip types.  So the default value is not
- * very useful.  I've redefined it for the 1.3 release so that it's
- * zero unless set by the user to something else, in which case we
- * try to respect it.
+ * numbers for different chip types.
  */
 static ushort ipath_kpiobufs;
 
@@ -546,9 +542,12 @@
 			pioavail = dd->ipath_pioavailregs_dma[i ^ 1];
 		else
 			pioavail = dd->ipath_pioavailregs_dma[i];
-		dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail) |
-			(~dd->ipath_pioavailkernel[i] <<
-			INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT);
+		/*
+		 * don't need to worry about ipath_pioavailkernel here
+		 * because we will call ipath_chg_pioavailkernel() later
+		 * in initialization, to busy out buffers as needed
+		 */
+		dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail);
 	}
 	/* can get counters, stats, etc. */
 	dd->ipath_flags |= IPATH_PRESENT;
@@ -708,12 +707,11 @@
 int ipath_init_chip(struct ipath_devdata *dd, int reinit)
 {
 	int ret = 0;
-	u32 val32, kpiobufs;
+	u32 kpiobufs, defkbufs;
 	u32 piobufs, uports;
 	u64 val;
 	struct ipath_portdata *pd;
 	gfp_t gfp_flags = GFP_USER | __GFP_COMP;
-	unsigned long flags;
 
 	ret = init_housekeeping(dd, reinit);
 	if (ret)
@@ -753,56 +751,46 @@
 	dd->ipath_pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2)
 		/ (sizeof(u64) * BITS_PER_BYTE / 2);
 	uports = dd->ipath_cfgports ? dd->ipath_cfgports - 1 : 0;
-	if (ipath_kpiobufs == 0) {
-		/* not set by user (this is default) */
-		if (piobufs > 144)
-			kpiobufs = 32;
-		else
-			kpiobufs = 16;
-	}
+	if (piobufs > 144)
+		defkbufs = 32 + dd->ipath_pioreserved;
 	else
-		kpiobufs = ipath_kpiobufs;
+		defkbufs = 16 + dd->ipath_pioreserved;
 
-	if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) {
+	if (ipath_kpiobufs && (ipath_kpiobufs +
+		(uports * IPATH_MIN_USER_PORT_BUFCNT)) > piobufs) {
 		int i = (int) piobufs -
 			(int) (uports * IPATH_MIN_USER_PORT_BUFCNT);
 		if (i < 1)
 			i = 1;
 		dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of "
 			 "%d for kernel leaves too few for %d user ports "
-			 "(%d each); using %u\n", kpiobufs,
+			 "(%d each); using %u\n", ipath_kpiobufs,
 			 piobufs, uports, IPATH_MIN_USER_PORT_BUFCNT, i);
 		/*
 		 * shouldn't change ipath_kpiobufs, because could be
 		 * different for different devices...
 		 */
 		kpiobufs = i;
-	}
+	} else if (ipath_kpiobufs)
+		kpiobufs = ipath_kpiobufs;
+	else
+		kpiobufs = defkbufs;
 	dd->ipath_lastport_piobuf = piobufs - kpiobufs;
 	dd->ipath_pbufsport =
 		uports ? dd->ipath_lastport_piobuf / uports : 0;
-	val32 = dd->ipath_lastport_piobuf - (dd->ipath_pbufsport * uports);
-	if (val32 > 0) {
-		ipath_dbg("allocating %u pbufs/port leaves %u unused, "
-			  "add to kernel\n", dd->ipath_pbufsport, val32);
-		dd->ipath_lastport_piobuf -= val32;
-		kpiobufs += val32;
-		ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n",
-			  dd->ipath_pbufsport, val32);
-	}
+	/* if not an even divisor, some user ports get extra buffers */
+	dd->ipath_ports_extrabuf = dd->ipath_lastport_piobuf -
+		(dd->ipath_pbufsport * uports);
+	if (dd->ipath_ports_extrabuf)
+		ipath_dbg("%u pbufs/port leaves some unused, add 1 buffer to "
+			"ports <= %u\n", dd->ipath_pbufsport,
+			dd->ipath_ports_extrabuf);
 	dd->ipath_lastpioindex = 0;
 	dd->ipath_lastpioindexl = dd->ipath_piobcnt2k;
-	ipath_chg_pioavailkernel(dd, 0, piobufs, 1);
+	/* ipath_pioavailshadow initialized earlier */
 	ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u "
 		   "each for %u user ports\n", kpiobufs,
 		   piobufs, dd->ipath_pbufsport, uports);
-	if (dd->ipath_pioupd_thresh) {
-		if (dd->ipath_pbufsport < dd->ipath_pioupd_thresh)
-			dd->ipath_pioupd_thresh = dd->ipath_pbufsport;
-		if (kpiobufs < dd->ipath_pioupd_thresh)
-			dd->ipath_pioupd_thresh = kpiobufs;
-	}
-
 	ret = dd->ipath_f_early_init(dd);
 	if (ret) {
 		ipath_dev_err(dd, "Early initialization failure\n");
@@ -810,13 +798,6 @@
 	}
 
 	/*
-	 * Cancel any possible active sends from early driver load.
-	 * Follows early_init because some chips have to initialize
-	 * PIO buffers in early_init to avoid false parity errors.
-	 */
-	ipath_cancel_sends(dd, 0);
-
-	/*
 	 * Early_init sets rcvhdrentsize and rcvhdrsize, so this must be
 	 * done after early_init.
 	 */
@@ -836,6 +817,7 @@
 
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_sendpioavailaddr,
 			 dd->ipath_pioavailregs_phys);
+
 	/*
 	 * this is to detect s/w errors, which the h/w works around by
 	 * ignoring the low 6 bits of address, if it wasn't aligned.
@@ -862,12 +844,6 @@
 			 ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED);
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL);
 
-	spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
-	dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE;
-	ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl);
-	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
-	spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
-
 	/*
 	 * before error clears, since we expect serdes pll errors during
 	 * this, the first time after reset
@@ -940,6 +916,19 @@
 	else
 		enable_chip(dd, reinit);
 
+	/* after enable_chip, so pioavailshadow setup */
+	ipath_chg_pioavailkernel(dd, 0, piobufs, 1);
+
+	/*
+	 * Cancel any possible active sends from early driver load.
+	 * Follows early_init because some chips have to initialize
+	 * PIO buffers in early_init to avoid false parity errors.
+	 * After enable and ipath_chg_pioavailkernel so we can safely
+	 * enable pioavail updates and PIOENABLE; packets are now
+	 * ready to go out.
+	 */
+	ipath_cancel_sends(dd, 1);
+
 	if (!reinit) {
 		/*
 		 * Used when we close a port, for DMA already in flight
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 1b58f47..26900b3 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -38,42 +38,12 @@
 #include "ipath_verbs.h"
 #include "ipath_common.h"
 
-/*
- * clear (write) a pio buffer, to clear a parity error.   This routine
- * should only be called when in freeze mode, and the buffer should be
- * canceled afterwards.
- */
-static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum)
-{
-	u32 __iomem *pbuf;
-	u32 dwcnt; /* dword count to write */
-	if (pnum < dd->ipath_piobcnt2k) {
-		pbuf = (u32 __iomem *) (dd->ipath_pio2kbase + pnum *
-			dd->ipath_palign);
-		dwcnt = dd->ipath_piosize2k >> 2;
-	}
-	else {
-		pbuf = (u32 __iomem *) (dd->ipath_pio4kbase +
-			(pnum - dd->ipath_piobcnt2k) * dd->ipath_4kalign);
-		dwcnt = dd->ipath_piosize4k >> 2;
-	}
-	dev_info(&dd->pcidev->dev,
-		"Rewrite PIO buffer %u, to recover from parity error\n",
-		pnum);
-
-	/* no flush required, since already in freeze */
-	writel(dwcnt + 1, pbuf);
-	while (--dwcnt)
-		writel(0, pbuf++);
-}
 
 /*
  * Called when we might have an error that is specific to a particular
  * PIO buffer, and may need to cancel that buffer, so it can be re-used.
- * If rewrite is true, and bits are set in the sendbufferror registers,
- * we'll write to the buffer, for error recovery on parity errors.
  */
-void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite)
+void ipath_disarm_senderrbufs(struct ipath_devdata *dd)
 {
 	u32 piobcnt;
 	unsigned long sbuf[4];
@@ -109,11 +79,8 @@
 		}
 
 		for (i = 0; i < piobcnt; i++)
-			if (test_bit(i, sbuf)) {
-				if (rewrite)
-					ipath_clrpiobuf(dd, i);
+			if (test_bit(i, sbuf))
 				ipath_disarm_piobufs(dd, i, 1);
-			}
 		/* ignore armlaunch errs for a bit */
 		dd->ipath_lastcancel = jiffies+3;
 	}
@@ -164,7 +131,7 @@
 {
 	u64 ignore_this_time = 0;
 
-	ipath_disarm_senderrbufs(dd, 0);
+	ipath_disarm_senderrbufs(dd);
 	if ((errs & E_SUM_LINK_PKTERRS) &&
 	    !(dd->ipath_flags & IPATH_LINKACTIVE)) {
 		/*
@@ -909,8 +876,8 @@
  * processes (causing armlaunch), send errors due to going into freeze mode,
  * etc., and try to avoid causing extra interrupts while doing so.
  * Forcibly update the in-memory pioavail register copies after cleanup
- * because the chip won't do it for anything changing while in freeze mode
- * (we don't want to wait for the next pio buffer state change).
+ * because the chip won't do it while in freeze mode (the register values
+ * themselves are kept correct).
  * Make sure that we don't lose any important interrupts by using the chip
  * feature that says that writing 0 to a bit in *clear that is set in
  * *status will cause an interrupt to be generated again (if allowed by
@@ -918,44 +885,23 @@
  */
 void ipath_clear_freeze(struct ipath_devdata *dd)
 {
-	int i, im;
-	u64 val;
-
 	/* disable error interrupts, to avoid confusion */
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL);
 
 	/* also disable interrupts; errormask is sometimes overwriten */
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL);
 
-	/*
-	 * clear all sends, because they have may been
-	 * completed by usercode while in freeze mode, and
-	 * therefore would not be sent, and eventually
-	 * might cause the process to run out of bufs
-	 */
-	ipath_cancel_sends(dd, 0);
+	ipath_cancel_sends(dd, 1);
+
+	/* clear the freeze, and be sure chip saw it */
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_control,
 			 dd->ipath_control);
+	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
 
-	/* ensure pio avail updates continue */
+	/* force in-memory update now we are out of freeze */
 	ipath_force_pio_avail_update(dd);
 
 	/*
-	 * We just enabled pioavailupdate, so dma copy is almost certainly
-	 * not yet right, so read the registers directly.  Similar to init
-	 */
-	for (i = 0; i < dd->ipath_pioavregs; i++) {
-		/* deal with 6110 chip bug */
-		im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ?
-			i ^ 1 : i;
-		val = ipath_read_kreg64(dd, (0x1000 / sizeof(u64)) + im);
-		dd->ipath_pioavailregs_dma[i] = cpu_to_le64(val);
-		dd->ipath_pioavailshadow[i] = val |
-			(~dd->ipath_pioavailkernel[i] <<
-			INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT);
-	}
-
-	/*
 	 * force new interrupt if any hwerr, error or interrupt bits are
 	 * still set, and clear "safe" send packet errors related to freeze
 	 * and cancelling sends.  Re-enable error interrupts before possible
@@ -1312,10 +1258,8 @@
 		ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
 		spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 
-		if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA))
-			handle_layer_pioavail(dd);
-		else
-			ipath_dbg("unexpected BUFAVAIL intr\n");
+		/* always process; sdma verbs uses PIO for acks and VL15  */
+		handle_layer_pioavail(dd);
 	}
 
 	ret = IRQ_HANDLED;
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 202337a..59a8b25 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -117,6 +117,10 @@
 	u16 port_subport_cnt;
 	/* non-zero if port is being shared. */
 	u16 port_subport_id;
+	/* number of pio bufs for this port (all procs, if shared) */
+	u32 port_piocnt;
+	/* first pio buffer for this port */
+	u32 port_pio_base;
 	/* chip offset of PIO buffers for this port */
 	u32 port_piobufs;
 	/* how many alloc_pages() chunks in port_rcvegrbuf_pages */
@@ -155,8 +159,8 @@
 	/* saved total number of polled urgent packets for poll edge trigger */
 	u32 port_urgent_poll;
 	/* pid of process using this port */
-	pid_t port_pid;
-	pid_t port_subpid[INFINIPATH_MAX_SUBPORT];
+	struct pid *port_pid;
+	struct pid *port_subpid[INFINIPATH_MAX_SUBPORT];
 	/* same size as task_struct .comm[] */
 	char port_comm[16];
 	/* pkeys set by this use of this port */
@@ -384,6 +388,8 @@
 	u32 ipath_lastrpkts;
 	/* pio bufs allocated per port */
 	u32 ipath_pbufsport;
+	/* if remainder on bufs/port, ports < extrabuf get 1 extra */
+	u32 ipath_ports_extrabuf;
 	u32 ipath_pioupd_thresh; /* update threshold, some chips */
 	/*
 	 * number of ports configured as max; zero is set to number chip
@@ -477,7 +483,7 @@
 
 	/* SendDMA related entries */
 	spinlock_t            ipath_sdma_lock;
-	u64                   ipath_sdma_status;
+	unsigned long         ipath_sdma_status;
 	unsigned long         ipath_sdma_abort_jiffies;
 	unsigned long         ipath_sdma_abort_intr_timeout;
 	unsigned long         ipath_sdma_buf_jiffies;
@@ -816,8 +822,8 @@
 #define IPATH_SDMA_DISARMED  1
 #define IPATH_SDMA_DISABLED  2
 #define IPATH_SDMA_LAYERBUF  3
-#define IPATH_SDMA_RUNNING  62
-#define IPATH_SDMA_SHUTDOWN 63
+#define IPATH_SDMA_RUNNING  30
+#define IPATH_SDMA_SHUTDOWN 31
 
 /* bit combinations that correspond to abort states */
 #define IPATH_SDMA_ABORT_NONE 0
@@ -1011,7 +1017,7 @@
 int ipath_update_eeprom_log(struct ipath_devdata *dd);
 void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr);
 u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
-void ipath_disarm_senderrbufs(struct ipath_devdata *, int);
+void ipath_disarm_senderrbufs(struct ipath_devdata *);
 void ipath_force_pio_avail_update(struct ipath_devdata *);
 void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev);
 
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index dd5b6e9..4715911 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -242,7 +242,6 @@
 {
 	struct ipath_qp *q, **qpp;
 	unsigned long flags;
-	int fnd = 0;
 
 	spin_lock_irqsave(&qpt->lock, flags);
 
@@ -253,51 +252,40 @@
 			*qpp = qp->next;
 			qp->next = NULL;
 			atomic_dec(&qp->refcount);
-			fnd = 1;
 			break;
 		}
 	}
 
 	spin_unlock_irqrestore(&qpt->lock, flags);
-
-	if (!fnd)
-		return;
-
-	free_qpn(qpt, qp->ibqp.qp_num);
-
-	wait_event(qp->wait, !atomic_read(&qp->refcount));
 }
 
 /**
- * ipath_free_all_qps - remove all QPs from the table
+ * ipath_free_all_qps - check for QPs still in use
  * @qpt: the QP table to empty
+ *
+ * There should not be any QPs still in use.
+ * Free memory for table.
  */
-void ipath_free_all_qps(struct ipath_qp_table *qpt)
+unsigned ipath_free_all_qps(struct ipath_qp_table *qpt)
 {
 	unsigned long flags;
-	struct ipath_qp *qp, *nqp;
-	u32 n;
+	struct ipath_qp *qp;
+	u32 n, qp_inuse = 0;
 
+	spin_lock_irqsave(&qpt->lock, flags);
 	for (n = 0; n < qpt->max; n++) {
-		spin_lock_irqsave(&qpt->lock, flags);
 		qp = qpt->table[n];
 		qpt->table[n] = NULL;
-		spin_unlock_irqrestore(&qpt->lock, flags);
 
-		while (qp) {
-			nqp = qp->next;
-			free_qpn(qpt, qp->ibqp.qp_num);
-			if (!atomic_dec_and_test(&qp->refcount) ||
-			    !ipath_destroy_qp(&qp->ibqp))
-				ipath_dbg("QP memory leak!\n");
-			qp = nqp;
-		}
+		for (; qp; qp = qp->next)
+			qp_inuse++;
 	}
+	spin_unlock_irqrestore(&qpt->lock, flags);
 
-	for (n = 0; n < ARRAY_SIZE(qpt->map); n++) {
+	for (n = 0; n < ARRAY_SIZE(qpt->map); n++)
 		if (qpt->map[n].page)
-			free_page((unsigned long)qpt->map[n].page);
-	}
+			free_page((unsigned long) qpt->map[n].page);
+	return qp_inuse;
 }
 
 /**
@@ -336,11 +324,12 @@
 	qp->remote_qpn = 0;
 	qp->qkey = 0;
 	qp->qp_access_flags = 0;
-	qp->s_busy = 0;
+	atomic_set(&qp->s_dma_busy, 0);
 	qp->s_flags &= IPATH_S_SIGNAL_REQ_WR;
 	qp->s_hdrwords = 0;
 	qp->s_wqe = NULL;
 	qp->s_pkt_delay = 0;
+	qp->s_draining = 0;
 	qp->s_psn = 0;
 	qp->r_psn = 0;
 	qp->r_msn = 0;
@@ -353,7 +342,8 @@
 	}
 	qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
 	qp->r_nak_state = 0;
-	qp->r_wrid_valid = 0;
+	qp->r_aflags = 0;
+	qp->r_flags = 0;
 	qp->s_rnr_timeout = 0;
 	qp->s_head = 0;
 	qp->s_tail = 0;
@@ -361,7 +351,6 @@
 	qp->s_last = 0;
 	qp->s_ssn = 1;
 	qp->s_lsn = 0;
-	qp->s_wait_credit = 0;
 	memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue));
 	qp->r_head_ack_queue = 0;
 	qp->s_tail_ack_queue = 0;
@@ -370,17 +359,17 @@
 		qp->r_rq.wq->head = 0;
 		qp->r_rq.wq->tail = 0;
 	}
-	qp->r_reuse_sge = 0;
 }
 
 /**
- * ipath_error_qp - put a QP into an error state
- * @qp: the QP to put into an error state
+ * ipath_error_qp - put a QP into the error state
+ * @qp: the QP to put into the error state
  * @err: the receive completion error to signal if a RWQE is active
  *
  * Flushes both send and receive work queues.
  * Returns true if last WQE event should be generated.
  * The QP s_lock should be held and interrupts disabled.
+ * If we are already in error state, just return.
  */
 
 int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
@@ -389,8 +378,10 @@
 	struct ib_wc wc;
 	int ret = 0;
 
-	ipath_dbg("QP%d/%d in error state (%d)\n",
-		  qp->ibqp.qp_num, qp->remote_qpn, err);
+	if (qp->state == IB_QPS_ERR)
+		goto bail;
+
+	qp->state = IB_QPS_ERR;
 
 	spin_lock(&dev->pending_lock);
 	if (!list_empty(&qp->timerwait))
@@ -399,39 +390,21 @@
 		list_del_init(&qp->piowait);
 	spin_unlock(&dev->pending_lock);
 
-	wc.vendor_err = 0;
-	wc.byte_len = 0;
-	wc.imm_data = 0;
+	/* Schedule the sending tasklet to drain the send work queue. */
+	if (qp->s_last != qp->s_head)
+		ipath_schedule_send(qp);
+
+	memset(&wc, 0, sizeof(wc));
 	wc.qp = &qp->ibqp;
-	wc.src_qp = 0;
-	wc.wc_flags = 0;
-	wc.pkey_index = 0;
-	wc.slid = 0;
-	wc.sl = 0;
-	wc.dlid_path_bits = 0;
-	wc.port_num = 0;
-	if (qp->r_wrid_valid) {
-		qp->r_wrid_valid = 0;
+	wc.opcode = IB_WC_RECV;
+
+	if (test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) {
 		wc.wr_id = qp->r_wr_id;
-		wc.opcode = IB_WC_RECV;
 		wc.status = err;
 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
 	}
 	wc.status = IB_WC_WR_FLUSH_ERR;
 
-	while (qp->s_last != qp->s_head) {
-		struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
-
-		wc.wr_id = wqe->wr.wr_id;
-		wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-		if (++qp->s_last >= qp->s_size)
-			qp->s_last = 0;
-		ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
-	}
-	qp->s_cur = qp->s_tail = qp->s_head;
-	qp->s_hdrwords = 0;
-	qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
-
 	if (qp->r_rq.wq) {
 		struct ipath_rwq *wq;
 		u32 head;
@@ -447,7 +420,6 @@
 		tail = wq->tail;
 		if (tail >= qp->r_rq.size)
 			tail = 0;
-		wc.opcode = IB_WC_RECV;
 		while (tail != head) {
 			wc.wr_id = get_rwqe_ptr(&qp->r_rq, tail)->wr_id;
 			if (++tail >= qp->r_rq.size)
@@ -460,6 +432,7 @@
 	} else if (qp->ibqp.event_handler)
 		ret = 1;
 
+bail:
 	return ret;
 }
 
@@ -478,11 +451,10 @@
 	struct ipath_ibdev *dev = to_idev(ibqp->device);
 	struct ipath_qp *qp = to_iqp(ibqp);
 	enum ib_qp_state cur_state, new_state;
-	unsigned long flags;
 	int lastwqe = 0;
 	int ret;
 
-	spin_lock_irqsave(&qp->s_lock, flags);
+	spin_lock_irq(&qp->s_lock);
 
 	cur_state = attr_mask & IB_QP_CUR_STATE ?
 		attr->cur_qp_state : qp->state;
@@ -535,16 +507,42 @@
 
 	switch (new_state) {
 	case IB_QPS_RESET:
+		if (qp->state != IB_QPS_RESET) {
+			qp->state = IB_QPS_RESET;
+			spin_lock(&dev->pending_lock);
+			if (!list_empty(&qp->timerwait))
+				list_del_init(&qp->timerwait);
+			if (!list_empty(&qp->piowait))
+				list_del_init(&qp->piowait);
+			spin_unlock(&dev->pending_lock);
+			qp->s_flags &= ~IPATH_S_ANY_WAIT;
+			spin_unlock_irq(&qp->s_lock);
+			/* Stop the sending tasklet */
+			tasklet_kill(&qp->s_task);
+			wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy));
+			spin_lock_irq(&qp->s_lock);
+		}
 		ipath_reset_qp(qp, ibqp->qp_type);
 		break;
 
+	case IB_QPS_SQD:
+		qp->s_draining = qp->s_last != qp->s_cur;
+		qp->state = new_state;
+		break;
+
+	case IB_QPS_SQE:
+		if (qp->ibqp.qp_type == IB_QPT_RC)
+			goto inval;
+		qp->state = new_state;
+		break;
+
 	case IB_QPS_ERR:
 		lastwqe = ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
 		break;
 
 	default:
+		qp->state = new_state;
 		break;
-
 	}
 
 	if (attr_mask & IB_QP_PKEY_INDEX)
@@ -597,8 +595,7 @@
 	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
 		qp->s_max_rd_atomic = attr->max_rd_atomic;
 
-	qp->state = new_state;
-	spin_unlock_irqrestore(&qp->s_lock, flags);
+	spin_unlock_irq(&qp->s_lock);
 
 	if (lastwqe) {
 		struct ib_event ev;
@@ -612,7 +609,7 @@
 	goto bail;
 
 inval:
-	spin_unlock_irqrestore(&qp->s_lock, flags);
+	spin_unlock_irq(&qp->s_lock);
 	ret = -EINVAL;
 
 bail:
@@ -643,7 +640,7 @@
 	attr->pkey_index = qp->s_pkey_index;
 	attr->alt_pkey_index = 0;
 	attr->en_sqd_async_notify = 0;
-	attr->sq_draining = 0;
+	attr->sq_draining = qp->s_draining;
 	attr->max_rd_atomic = qp->s_max_rd_atomic;
 	attr->max_dest_rd_atomic = qp->r_max_rd_atomic;
 	attr->min_rnr_timer = qp->r_min_rnr_timer;
@@ -833,6 +830,7 @@
 		spin_lock_init(&qp->r_rq.lock);
 		atomic_set(&qp->refcount, 0);
 		init_waitqueue_head(&qp->wait);
+		init_waitqueue_head(&qp->wait_dma);
 		tasklet_init(&qp->s_task, ipath_do_send, (unsigned long)qp);
 		INIT_LIST_HEAD(&qp->piowait);
 		INIT_LIST_HEAD(&qp->timerwait);
@@ -926,6 +924,7 @@
 	else
 		vfree(qp->r_rq.wq);
 	ipath_free_qp(&dev->qp_table, qp);
+	free_qpn(&dev->qp_table, qp->ibqp.qp_num);
 bail_qp:
 	kfree(qp);
 bail_swq:
@@ -947,41 +946,44 @@
 {
 	struct ipath_qp *qp = to_iqp(ibqp);
 	struct ipath_ibdev *dev = to_idev(ibqp->device);
-	unsigned long flags;
 
-	spin_lock_irqsave(&qp->s_lock, flags);
-	qp->state = IB_QPS_ERR;
-	spin_unlock_irqrestore(&qp->s_lock, flags);
-	spin_lock(&dev->n_qps_lock);
-	dev->n_qps_allocated--;
-	spin_unlock(&dev->n_qps_lock);
+	/* Make sure HW and driver activity is stopped. */
+	spin_lock_irq(&qp->s_lock);
+	if (qp->state != IB_QPS_RESET) {
+		qp->state = IB_QPS_RESET;
+		spin_lock(&dev->pending_lock);
+		if (!list_empty(&qp->timerwait))
+			list_del_init(&qp->timerwait);
+		if (!list_empty(&qp->piowait))
+			list_del_init(&qp->piowait);
+		spin_unlock(&dev->pending_lock);
+		qp->s_flags &= ~IPATH_S_ANY_WAIT;
+		spin_unlock_irq(&qp->s_lock);
+		/* Stop the sending tasklet */
+		tasklet_kill(&qp->s_task);
+		wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy));
+	} else
+		spin_unlock_irq(&qp->s_lock);
 
-	/* Stop the sending tasklet. */
-	tasklet_kill(&qp->s_task);
+	ipath_free_qp(&dev->qp_table, qp);
 
 	if (qp->s_tx) {
 		atomic_dec(&qp->refcount);
 		if (qp->s_tx->txreq.flags & IPATH_SDMA_TXREQ_F_FREEBUF)
 			kfree(qp->s_tx->txreq.map_addr);
+		spin_lock_irq(&dev->pending_lock);
+		list_add(&qp->s_tx->txreq.list, &dev->txreq_free);
+		spin_unlock_irq(&dev->pending_lock);
+		qp->s_tx = NULL;
 	}
 
-	/* Make sure the QP isn't on the timeout list. */
-	spin_lock_irqsave(&dev->pending_lock, flags);
-	if (!list_empty(&qp->timerwait))
-		list_del_init(&qp->timerwait);
-	if (!list_empty(&qp->piowait))
-		list_del_init(&qp->piowait);
-	if (qp->s_tx)
-		list_add(&qp->s_tx->txreq.list, &dev->txreq_free);
-	spin_unlock_irqrestore(&dev->pending_lock, flags);
+	wait_event(qp->wait, !atomic_read(&qp->refcount));
 
-	/*
-	 * Make sure that the QP is not in the QPN table so receive
-	 * interrupts will discard packets for this QP.  XXX Also remove QP
-	 * from multicast table.
-	 */
-	if (atomic_read(&qp->refcount) != 0)
-		ipath_free_qp(&dev->qp_table, qp);
+	/* all user's cleaned up, mark it available */
+	free_qpn(&dev->qp_table, qp->ibqp.qp_num);
+	spin_lock(&dev->n_qps_lock);
+	dev->n_qps_allocated--;
+	spin_unlock(&dev->n_qps_lock);
 
 	if (qp->ip)
 		kref_put(&qp->ip->ref, ipath_release_mmap_info);
@@ -1026,48 +1028,6 @@
 }
 
 /**
- * ipath_sqerror_qp - put a QP's send queue into an error state
- * @qp: QP who's send queue will be put into an error state
- * @wc: the WC responsible for putting the QP in this state
- *
- * Flushes the send work queue.
- * The QP s_lock should be held and interrupts disabled.
- */
-
-void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc)
-{
-	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
-	struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
-
-	ipath_dbg("Send queue error on QP%d/%d: err: %d\n",
-		  qp->ibqp.qp_num, qp->remote_qpn, wc->status);
-
-	spin_lock(&dev->pending_lock);
-	if (!list_empty(&qp->timerwait))
-		list_del_init(&qp->timerwait);
-	if (!list_empty(&qp->piowait))
-		list_del_init(&qp->piowait);
-	spin_unlock(&dev->pending_lock);
-
-	ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
-	if (++qp->s_last >= qp->s_size)
-		qp->s_last = 0;
-
-	wc->status = IB_WC_WR_FLUSH_ERR;
-
-	while (qp->s_last != qp->s_head) {
-		wqe = get_swqe_ptr(qp, qp->s_last);
-		wc->wr_id = wqe->wr.wr_id;
-		wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-		ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
-		if (++qp->s_last >= qp->s_size)
-			qp->s_last = 0;
-	}
-	qp->s_cur = qp->s_tail = qp->s_head;
-	qp->state = IB_QPS_SQE;
-}
-
-/**
  * ipath_get_credit - flush the send work queue of a QP
  * @qp: the qp who's send work queue to flush
  * @aeth: the Acknowledge Extended Transport Header
@@ -1093,9 +1053,10 @@
 	}
 
 	/* Restart sending if it was blocked due to lack of credits. */
-	if (qp->s_cur != qp->s_head &&
+	if ((qp->s_flags & IPATH_S_WAIT_SSN_CREDIT) &&
+	    qp->s_cur != qp->s_head &&
 	    (qp->s_lsn == (u32) -1 ||
 	     ipath_cmp24(get_swqe_ptr(qp, qp->s_cur)->ssn,
 			 qp->s_lsn + 1) <= 0))
-		tasklet_hi_schedule(&qp->s_task);
+		ipath_schedule_send(qp);
 }
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index c405dfb..108df66 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -92,6 +92,10 @@
 	u32 bth0;
 	u32 bth2;
 
+	/* Don't send an ACK if we aren't supposed to. */
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
+		goto bail;
+
 	/* header size in 32-bit words LRH+BTH = (8+12)/4. */
 	hwords = 5;
 
@@ -238,14 +242,25 @@
 	    ipath_make_rc_ack(dev, qp, ohdr, pmtu))
 		goto done;
 
-	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) ||
-	    qp->s_rnr_timeout || qp->s_wait_credit)
-		goto bail;
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) {
+		if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
+			goto bail;
+		/* We are in the error state, flush the work request. */
+		if (qp->s_last == qp->s_head)
+			goto bail;
+		/* If DMAs are in progress, we can't flush immediately. */
+		if (atomic_read(&qp->s_dma_busy)) {
+			qp->s_flags |= IPATH_S_WAIT_DMA;
+			goto bail;
+		}
+		wqe = get_swqe_ptr(qp, qp->s_last);
+		ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
+		goto done;
+	}
 
-	/* Limit the number of packets sent without an ACK. */
-	if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT) > 0) {
-		qp->s_wait_credit = 1;
-		dev->n_rc_stalls++;
+	/* Leave BUSY set until RNR timeout. */
+	if (qp->s_rnr_timeout) {
+		qp->s_flags |= IPATH_S_WAITING;
 		goto bail;
 	}
 
@@ -257,6 +272,9 @@
 	wqe = get_swqe_ptr(qp, qp->s_cur);
 	switch (qp->s_state) {
 	default:
+		if (!(ib_ipath_state_ops[qp->state] &
+		    IPATH_PROCESS_NEXT_SEND_OK))
+			goto bail;
 		/*
 		 * Resend an old request or start a new one.
 		 *
@@ -294,8 +312,10 @@
 		case IB_WR_SEND_WITH_IMM:
 			/* If no credit, return. */
 			if (qp->s_lsn != (u32) -1 &&
-			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0)
+			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) {
+				qp->s_flags |= IPATH_S_WAIT_SSN_CREDIT;
 				goto bail;
+			}
 			wqe->lpsn = wqe->psn;
 			if (len > pmtu) {
 				wqe->lpsn += (len - 1) / pmtu;
@@ -325,8 +345,10 @@
 		case IB_WR_RDMA_WRITE_WITH_IMM:
 			/* If no credit, return. */
 			if (qp->s_lsn != (u32) -1 &&
-			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0)
+			    ipath_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) {
+				qp->s_flags |= IPATH_S_WAIT_SSN_CREDIT;
 				goto bail;
+			}
 			ohdr->u.rc.reth.vaddr =
 				cpu_to_be64(wqe->wr.wr.rdma.remote_addr);
 			ohdr->u.rc.reth.rkey =
@@ -570,7 +592,11 @@
 	ipath_make_ruc_header(dev, qp, ohdr, bth0 | (qp->s_state << 24), bth2);
 done:
 	ret = 1;
+	goto unlock;
+
 bail:
+	qp->s_flags &= ~IPATH_S_BUSY;
+unlock:
 	spin_unlock_irqrestore(&qp->s_lock, flags);
 	return ret;
 }
@@ -606,7 +632,11 @@
 
 	spin_unlock_irqrestore(&qp->s_lock, flags);
 
+	/* Don't try to send ACKs if the link isn't ACTIVE */
 	dd = dev->dd;
+	if (!(dd->ipath_flags & IPATH_LINKACTIVE))
+		goto done;
+
 	piobuf = ipath_getpiobuf(dd, 0, NULL);
 	if (!piobuf) {
 		/*
@@ -668,15 +698,16 @@
 	goto done;
 
 queue_ack:
-	dev->n_rc_qacks++;
-	qp->s_flags |= IPATH_S_ACK_PENDING;
-	qp->s_nak_state = qp->r_nak_state;
-	qp->s_ack_psn = qp->r_ack_psn;
+	if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK) {
+		dev->n_rc_qacks++;
+		qp->s_flags |= IPATH_S_ACK_PENDING;
+		qp->s_nak_state = qp->r_nak_state;
+		qp->s_ack_psn = qp->r_ack_psn;
+
+		/* Schedule the send tasklet. */
+		ipath_schedule_send(qp);
+	}
 	spin_unlock_irqrestore(&qp->s_lock, flags);
-
-	/* Call ipath_do_rc_send() in another thread. */
-	tasklet_hi_schedule(&qp->s_task);
-
 done:
 	return;
 }
@@ -735,7 +766,7 @@
 	/*
 	 * Set the state to restart in the middle of a request.
 	 * Don't change the s_sge, s_cur_sge, or s_cur_size.
-	 * See ipath_do_rc_send().
+	 * See ipath_make_rc_req().
 	 */
 	switch (opcode) {
 	case IB_WR_SEND:
@@ -771,27 +802,14 @@
  *
  * The QP s_lock should be held and interrupts disabled.
  */
-void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
+void ipath_restart_rc(struct ipath_qp *qp, u32 psn)
 {
 	struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
 	struct ipath_ibdev *dev;
 
 	if (qp->s_retry == 0) {
-		wc->wr_id = wqe->wr.wr_id;
-		wc->status = IB_WC_RETRY_EXC_ERR;
-		wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-		wc->vendor_err = 0;
-		wc->byte_len = 0;
-		wc->qp = &qp->ibqp;
-		wc->imm_data = 0;
-		wc->src_qp = qp->remote_qpn;
-		wc->wc_flags = 0;
-		wc->pkey_index = 0;
-		wc->slid = qp->remote_ah_attr.dlid;
-		wc->sl = qp->remote_ah_attr.sl;
-		wc->dlid_path_bits = 0;
-		wc->port_num = 0;
-		ipath_sqerror_qp(qp, wc);
+		ipath_send_complete(qp, wqe, IB_WC_RETRY_EXC_ERR);
+		ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
 		goto bail;
 	}
 	qp->s_retry--;
@@ -804,6 +822,8 @@
 	spin_lock(&dev->pending_lock);
 	if (!list_empty(&qp->timerwait))
 		list_del_init(&qp->timerwait);
+	if (!list_empty(&qp->piowait))
+		list_del_init(&qp->piowait);
 	spin_unlock(&dev->pending_lock);
 
 	if (wqe->wr.opcode == IB_WR_RDMA_READ)
@@ -812,7 +832,7 @@
 		dev->n_rc_resends += (qp->s_psn - psn) & IPATH_PSN_MASK;
 
 	reset_psn(qp, psn);
-	tasklet_hi_schedule(&qp->s_task);
+	ipath_schedule_send(qp);
 
 bail:
 	return;
@@ -820,13 +840,7 @@
 
 static inline void update_last_psn(struct ipath_qp *qp, u32 psn)
 {
-	if (qp->s_last_psn != psn) {
-		qp->s_last_psn = psn;
-		if (qp->s_wait_credit) {
-			qp->s_wait_credit = 0;
-			tasklet_hi_schedule(&qp->s_task);
-		}
-	}
+	qp->s_last_psn = psn;
 }
 
 /**
@@ -845,6 +859,7 @@
 {
 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
 	struct ib_wc wc;
+	enum ib_wc_status status;
 	struct ipath_swqe *wqe;
 	int ret = 0;
 	u32 ack_psn;
@@ -909,7 +924,7 @@
 			 */
 			update_last_psn(qp, wqe->psn - 1);
 			/* Retry this request. */
-			ipath_restart_rc(qp, wqe->psn, &wc);
+			ipath_restart_rc(qp, wqe->psn);
 			/*
 			 * No need to process the ACK/NAK since we are
 			 * restarting an earlier request.
@@ -925,32 +940,23 @@
 		     wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)) {
 			qp->s_num_rd_atomic--;
 			/* Restart sending task if fence is complete */
-			if ((qp->s_flags & IPATH_S_FENCE_PENDING) &&
-			    !qp->s_num_rd_atomic) {
-				qp->s_flags &= ~IPATH_S_FENCE_PENDING;
-				tasklet_hi_schedule(&qp->s_task);
-			} else if (qp->s_flags & IPATH_S_RDMAR_PENDING) {
-				qp->s_flags &= ~IPATH_S_RDMAR_PENDING;
-				tasklet_hi_schedule(&qp->s_task);
-			}
+			if (((qp->s_flags & IPATH_S_FENCE_PENDING) &&
+			     !qp->s_num_rd_atomic) ||
+			    qp->s_flags & IPATH_S_RDMAR_PENDING)
+				ipath_schedule_send(qp);
 		}
 		/* Post a send completion queue entry if requested. */
 		if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
 		    (wqe->wr.send_flags & IB_SEND_SIGNALED)) {
+			memset(&wc, 0, sizeof wc);
 			wc.wr_id = wqe->wr.wr_id;
 			wc.status = IB_WC_SUCCESS;
 			wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-			wc.vendor_err = 0;
 			wc.byte_len = wqe->length;
-			wc.imm_data = 0;
 			wc.qp = &qp->ibqp;
 			wc.src_qp = qp->remote_qpn;
-			wc.wc_flags = 0;
-			wc.pkey_index = 0;
 			wc.slid = qp->remote_ah_attr.dlid;
 			wc.sl = qp->remote_ah_attr.sl;
-			wc.dlid_path_bits = 0;
-			wc.port_num = 0;
 			ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0);
 		}
 		qp->s_retry = qp->s_retry_cnt;
@@ -971,6 +977,8 @@
 		} else {
 			if (++qp->s_last >= qp->s_size)
 				qp->s_last = 0;
+			if (qp->state == IB_QPS_SQD && qp->s_last == qp->s_cur)
+				qp->s_draining = 0;
 			if (qp->s_last == qp->s_tail)
 				break;
 			wqe = get_swqe_ptr(qp, qp->s_last);
@@ -994,7 +1002,7 @@
 			 */
 			if (ipath_cmp24(qp->s_psn, psn) <= 0) {
 				reset_psn(qp, psn + 1);
-				tasklet_hi_schedule(&qp->s_task);
+				ipath_schedule_send(qp);
 			}
 		} else if (ipath_cmp24(qp->s_psn, psn) <= 0) {
 			qp->s_state = OP(SEND_LAST);
@@ -1012,7 +1020,7 @@
 		if (qp->s_last == qp->s_tail)
 			goto bail;
 		if (qp->s_rnr_retry == 0) {
-			wc.status = IB_WC_RNR_RETRY_EXC_ERR;
+			status = IB_WC_RNR_RETRY_EXC_ERR;
 			goto class_b;
 		}
 		if (qp->s_rnr_retry_cnt < 7)
@@ -1033,6 +1041,7 @@
 			ib_ipath_rnr_table[(aeth >> IPATH_AETH_CREDIT_SHIFT) &
 					   IPATH_AETH_CREDIT_MASK];
 		ipath_insert_rnr_queue(qp);
+		ipath_schedule_send(qp);
 		goto bail;
 
 	case 3:		/* NAK */
@@ -1050,37 +1059,25 @@
 			 * RDMA READ response which terminates the RDMA
 			 * READ.
 			 */
-			ipath_restart_rc(qp, psn, &wc);
+			ipath_restart_rc(qp, psn);
 			break;
 
 		case 1:	/* Invalid Request */
-			wc.status = IB_WC_REM_INV_REQ_ERR;
+			status = IB_WC_REM_INV_REQ_ERR;
 			dev->n_other_naks++;
 			goto class_b;
 
 		case 2:	/* Remote Access Error */
-			wc.status = IB_WC_REM_ACCESS_ERR;
+			status = IB_WC_REM_ACCESS_ERR;
 			dev->n_other_naks++;
 			goto class_b;
 
 		case 3:	/* Remote Operation Error */
-			wc.status = IB_WC_REM_OP_ERR;
+			status = IB_WC_REM_OP_ERR;
 			dev->n_other_naks++;
 		class_b:
-			wc.wr_id = wqe->wr.wr_id;
-			wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-			wc.vendor_err = 0;
-			wc.byte_len = 0;
-			wc.qp = &qp->ibqp;
-			wc.imm_data = 0;
-			wc.src_qp = qp->remote_qpn;
-			wc.wc_flags = 0;
-			wc.pkey_index = 0;
-			wc.slid = qp->remote_ah_attr.dlid;
-			wc.sl = qp->remote_ah_attr.sl;
-			wc.dlid_path_bits = 0;
-			wc.port_num = 0;
-			ipath_sqerror_qp(qp, &wc);
+			ipath_send_complete(qp, wqe, status);
+			ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
 			break;
 
 		default:
@@ -1126,8 +1123,8 @@
 				     int header_in_data)
 {
 	struct ipath_swqe *wqe;
+	enum ib_wc_status status;
 	unsigned long flags;
-	struct ib_wc wc;
 	int diff;
 	u32 pad;
 	u32 aeth;
@@ -1135,6 +1132,10 @@
 
 	spin_lock_irqsave(&qp->s_lock, flags);
 
+	/* Double check we can process this now that we hold the s_lock. */
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
+		goto ack_done;
+
 	/* Ignore invalid responses. */
 	if (ipath_cmp24(psn, qp->s_next_psn) >= 0)
 		goto ack_done;
@@ -1159,6 +1160,7 @@
 	if (unlikely(qp->s_last == qp->s_tail))
 		goto ack_done;
 	wqe = get_swqe_ptr(qp, qp->s_last);
+	status = IB_WC_SUCCESS;
 
 	switch (opcode) {
 	case OP(ACKNOWLEDGE):
@@ -1187,6 +1189,7 @@
 		wqe = get_swqe_ptr(qp, qp->s_last);
 		if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
 			goto ack_op_err;
+		qp->r_flags &= ~IPATH_R_RDMAR_SEQ;
 		/*
 		 * If this is a response to a resent RDMA read, we
 		 * have to be careful to copy the data to the right
@@ -1200,7 +1203,10 @@
 		/* no AETH, no ACK */
 		if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
 			dev->n_rdma_seq++;
-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+			if (qp->r_flags & IPATH_R_RDMAR_SEQ)
+				goto ack_done;
+			qp->r_flags |= IPATH_R_RDMAR_SEQ;
+			ipath_restart_rc(qp, qp->s_last_psn + 1);
 			goto ack_done;
 		}
 		if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
@@ -1261,7 +1267,10 @@
 		/* ACKs READ req. */
 		if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
 			dev->n_rdma_seq++;
-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+			if (qp->r_flags & IPATH_R_RDMAR_SEQ)
+				goto ack_done;
+			qp->r_flags |= IPATH_R_RDMAR_SEQ;
+			ipath_restart_rc(qp, qp->s_last_psn + 1);
 			goto ack_done;
 		}
 		if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
@@ -1291,31 +1300,16 @@
 		goto ack_done;
 	}
 
-ack_done:
-	spin_unlock_irqrestore(&qp->s_lock, flags);
-	goto bail;
-
 ack_op_err:
-	wc.status = IB_WC_LOC_QP_OP_ERR;
+	status = IB_WC_LOC_QP_OP_ERR;
 	goto ack_err;
 
 ack_len_err:
-	wc.status = IB_WC_LOC_LEN_ERR;
+	status = IB_WC_LOC_LEN_ERR;
 ack_err:
-	wc.wr_id = wqe->wr.wr_id;
-	wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-	wc.vendor_err = 0;
-	wc.byte_len = 0;
-	wc.imm_data = 0;
-	wc.qp = &qp->ibqp;
-	wc.src_qp = qp->remote_qpn;
-	wc.wc_flags = 0;
-	wc.pkey_index = 0;
-	wc.slid = qp->remote_ah_attr.dlid;
-	wc.sl = qp->remote_ah_attr.sl;
-	wc.dlid_path_bits = 0;
-	wc.port_num = 0;
-	ipath_sqerror_qp(qp, &wc);
+	ipath_send_complete(qp, wqe, status);
+	ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);
+ack_done:
 	spin_unlock_irqrestore(&qp->s_lock, flags);
 bail:
 	return;
@@ -1384,7 +1378,12 @@
 	psn &= IPATH_PSN_MASK;
 	e = NULL;
 	old_req = 1;
+
 	spin_lock_irqsave(&qp->s_lock, flags);
+	/* Double check we can process this now that we hold the s_lock. */
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
+		goto unlock_done;
+
 	for (i = qp->r_head_ack_queue; ; i = prev) {
 		if (i == qp->s_tail_ack_queue)
 			old_req = 0;
@@ -1512,7 +1511,7 @@
 		break;
 	}
 	qp->r_nak_state = 0;
-	tasklet_hi_schedule(&qp->s_task);
+	ipath_schedule_send(qp);
 
 unlock_done:
 	spin_unlock_irqrestore(&qp->s_lock, flags);
@@ -1523,13 +1522,12 @@
 	return 0;
 }
 
-static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
+void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
 {
 	unsigned long flags;
 	int lastwqe;
 
 	spin_lock_irqsave(&qp->s_lock, flags);
-	qp->state = IB_QPS_ERR;
 	lastwqe = ipath_error_qp(qp, err);
 	spin_unlock_irqrestore(&qp->s_lock, flags);
 
@@ -1545,18 +1543,15 @@
 
 static inline void ipath_update_ack_queue(struct ipath_qp *qp, unsigned n)
 {
-	unsigned long flags;
 	unsigned next;
 
 	next = n + 1;
 	if (next > IPATH_MAX_RDMA_ATOMIC)
 		next = 0;
-	spin_lock_irqsave(&qp->s_lock, flags);
 	if (n == qp->s_tail_ack_queue) {
 		qp->s_tail_ack_queue = next;
 		qp->s_ack_state = OP(ACKNOWLEDGE);
 	}
-	spin_unlock_irqrestore(&qp->s_lock, flags);
 }
 
 /**
@@ -1585,6 +1580,7 @@
 	int diff;
 	struct ib_reth *reth;
 	int header_in_data;
+	unsigned long flags;
 
 	/* Validate the SLID. See Ch. 9.6.1.5 */
 	if (unlikely(be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid))
@@ -1643,11 +1639,7 @@
 		    opcode == OP(SEND_LAST) ||
 		    opcode == OP(SEND_LAST_WITH_IMMEDIATE))
 			break;
-	nack_inv:
-		ipath_rc_error(qp, IB_WC_REM_INV_REQ_ERR);
-		qp->r_nak_state = IB_NAK_INVALID_REQUEST;
-		qp->r_ack_psn = qp->r_psn;
-		goto send_ack;
+		goto nack_inv;
 
 	case OP(RDMA_WRITE_FIRST):
 	case OP(RDMA_WRITE_MIDDLE):
@@ -1673,18 +1665,13 @@
 		break;
 	}
 
-	wc.imm_data = 0;
-	wc.wc_flags = 0;
+	memset(&wc, 0, sizeof wc);
 
 	/* OK, process the packet. */
 	switch (opcode) {
 	case OP(SEND_FIRST):
-		if (!ipath_get_rwqe(qp, 0)) {
-		rnr_nak:
-			qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer;
-			qp->r_ack_psn = qp->r_psn;
-			goto send_ack;
-		}
+		if (!ipath_get_rwqe(qp, 0))
+			goto rnr_nak;
 		qp->r_rcv_len = 0;
 		/* FALLTHROUGH */
 	case OP(SEND_MIDDLE):
@@ -1741,20 +1728,19 @@
 			goto nack_inv;
 		ipath_copy_sge(&qp->r_sge, data, tlen);
 		qp->r_msn++;
-		if (!qp->r_wrid_valid)
+		if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags))
 			break;
-		qp->r_wrid_valid = 0;
 		wc.wr_id = qp->r_wr_id;
 		wc.status = IB_WC_SUCCESS;
-		wc.opcode = IB_WC_RECV;
-		wc.vendor_err = 0;
+		if (opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE) ||
+		    opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE))
+			wc.opcode = IB_WC_RECV_RDMA_WITH_IMM;
+		else
+			wc.opcode = IB_WC_RECV;
 		wc.qp = &qp->ibqp;
 		wc.src_qp = qp->remote_qpn;
-		wc.pkey_index = 0;
 		wc.slid = qp->remote_ah_attr.dlid;
 		wc.sl = qp->remote_ah_attr.sl;
-		wc.dlid_path_bits = 0;
-		wc.port_num = 0;
 		/* Signal completion event if the solicited bit is set. */
 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
 			       (ohdr->bth[0] &
@@ -1815,9 +1801,13 @@
 		next = qp->r_head_ack_queue + 1;
 		if (next > IPATH_MAX_RDMA_ATOMIC)
 			next = 0;
+		spin_lock_irqsave(&qp->s_lock, flags);
+		/* Double check we can process this while holding the s_lock. */
+		if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
+			goto unlock;
 		if (unlikely(next == qp->s_tail_ack_queue)) {
 			if (!qp->s_ack_queue[next].sent)
-				goto nack_inv;
+				goto nack_inv_unlck;
 			ipath_update_ack_queue(qp, next);
 		}
 		e = &qp->s_ack_queue[qp->r_head_ack_queue];
@@ -1838,7 +1828,7 @@
 			ok = ipath_rkey_ok(qp, &e->rdma_sge, len, vaddr,
 					   rkey, IB_ACCESS_REMOTE_READ);
 			if (unlikely(!ok))
-				goto nack_acc;
+				goto nack_acc_unlck;
 			/*
 			 * Update the next expected PSN.  We add 1 later
 			 * below, so only add the remainder here.
@@ -1865,13 +1855,12 @@
 		qp->r_psn++;
 		qp->r_state = opcode;
 		qp->r_nak_state = 0;
-		barrier();
 		qp->r_head_ack_queue = next;
 
-		/* Call ipath_do_rc_send() in another thread. */
-		tasklet_hi_schedule(&qp->s_task);
+		/* Schedule the send tasklet. */
+		ipath_schedule_send(qp);
 
-		goto done;
+		goto unlock;
 	}
 
 	case OP(COMPARE_SWAP):
@@ -1890,9 +1879,13 @@
 		next = qp->r_head_ack_queue + 1;
 		if (next > IPATH_MAX_RDMA_ATOMIC)
 			next = 0;
+		spin_lock_irqsave(&qp->s_lock, flags);
+		/* Double check we can process this while holding the s_lock. */
+		if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK))
+			goto unlock;
 		if (unlikely(next == qp->s_tail_ack_queue)) {
 			if (!qp->s_ack_queue[next].sent)
-				goto nack_inv;
+				goto nack_inv_unlck;
 			ipath_update_ack_queue(qp, next);
 		}
 		if (!header_in_data)
@@ -1902,13 +1895,13 @@
 		vaddr = ((u64) be32_to_cpu(ateth->vaddr[0]) << 32) |
 			be32_to_cpu(ateth->vaddr[1]);
 		if (unlikely(vaddr & (sizeof(u64) - 1)))
-			goto nack_inv;
+			goto nack_inv_unlck;
 		rkey = be32_to_cpu(ateth->rkey);
 		/* Check rkey & NAK */
 		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge,
 					    sizeof(u64), vaddr, rkey,
 					    IB_ACCESS_REMOTE_ATOMIC)))
-			goto nack_acc;
+			goto nack_acc_unlck;
 		/* Perform atomic OP and save result. */
 		maddr = (atomic64_t *) qp->r_sge.sge.vaddr;
 		sdata = be64_to_cpu(ateth->swap_data);
@@ -1925,13 +1918,12 @@
 		qp->r_psn++;
 		qp->r_state = opcode;
 		qp->r_nak_state = 0;
-		barrier();
 		qp->r_head_ack_queue = next;
 
-		/* Call ipath_do_rc_send() in another thread. */
-		tasklet_hi_schedule(&qp->s_task);
+		/* Schedule the send tasklet. */
+		ipath_schedule_send(qp);
 
-		goto done;
+		goto unlock;
 	}
 
 	default:
@@ -1947,14 +1939,31 @@
 		goto send_ack;
 	goto done;
 
+rnr_nak:
+	qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer;
+	qp->r_ack_psn = qp->r_psn;
+	goto send_ack;
+
+nack_inv_unlck:
+	spin_unlock_irqrestore(&qp->s_lock, flags);
+nack_inv:
+	ipath_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
+	qp->r_nak_state = IB_NAK_INVALID_REQUEST;
+	qp->r_ack_psn = qp->r_psn;
+	goto send_ack;
+
+nack_acc_unlck:
+	spin_unlock_irqrestore(&qp->s_lock, flags);
 nack_acc:
-	ipath_rc_error(qp, IB_WC_REM_ACCESS_ERR);
+	ipath_rc_error(qp, IB_WC_LOC_PROT_ERR);
 	qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR;
 	qp->r_ack_psn = qp->r_psn;
-
 send_ack:
 	send_rc_ack(qp);
+	goto done;
 
+unlock:
+	spin_unlock_irqrestore(&qp->s_lock, flags);
 done:
 	return;
 }
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index 8ac5c1d..a4b5521 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
+ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -78,6 +78,7 @@
  * ipath_insert_rnr_queue - put QP on the RNR timeout list for the device
  * @qp: the QP
  *
+ * Called with the QP s_lock held and interrupts disabled.
  * XXX Use a simple list for now.  We might need a priority
  * queue if we have lots of QPs waiting for RNR timeouts
  * but that should be rare.
@@ -85,9 +86,9 @@
 void ipath_insert_rnr_queue(struct ipath_qp *qp)
 {
 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
-	unsigned long flags;
 
-	spin_lock_irqsave(&dev->pending_lock, flags);
+	/* We already did a spin_lock_irqsave(), so just use spin_lock */
+	spin_lock(&dev->pending_lock);
 	if (list_empty(&dev->rnrwait))
 		list_add(&qp->timerwait, &dev->rnrwait);
 	else {
@@ -109,7 +110,7 @@
 			nqp->s_rnr_timeout -= qp->s_rnr_timeout;
 		list_add(&qp->timerwait, l);
 	}
-	spin_unlock_irqrestore(&dev->pending_lock, flags);
+	spin_unlock(&dev->pending_lock);
 }
 
 /**
@@ -140,20 +141,11 @@
 	goto bail;
 
 bad_lkey:
+	memset(&wc, 0, sizeof(wc));
 	wc.wr_id = wqe->wr_id;
 	wc.status = IB_WC_LOC_PROT_ERR;
 	wc.opcode = IB_WC_RECV;
-	wc.vendor_err = 0;
-	wc.byte_len = 0;
-	wc.imm_data = 0;
 	wc.qp = &qp->ibqp;
-	wc.src_qp = 0;
-	wc.wc_flags = 0;
-	wc.pkey_index = 0;
-	wc.slid = 0;
-	wc.sl = 0;
-	wc.dlid_path_bits = 0;
-	wc.port_num = 0;
 	/* Signal solicited completion event. */
 	ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
 	ret = 0;
@@ -194,6 +186,11 @@
 	}
 
 	spin_lock_irqsave(&rq->lock, flags);
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) {
+		ret = 0;
+		goto unlock;
+	}
+
 	wq = rq->wq;
 	tail = wq->tail;
 	/* Validate tail before using it since it is user writable. */
@@ -201,9 +198,8 @@
 		tail = 0;
 	do {
 		if (unlikely(tail == wq->head)) {
-			spin_unlock_irqrestore(&rq->lock, flags);
 			ret = 0;
-			goto bail;
+			goto unlock;
 		}
 		/* Make sure entry is read after head index is read. */
 		smp_rmb();
@@ -216,7 +212,7 @@
 	wq->tail = tail;
 
 	ret = 1;
-	qp->r_wrid_valid = 1;
+	set_bit(IPATH_R_WRID_VALID, &qp->r_aflags);
 	if (handler) {
 		u32 n;
 
@@ -243,8 +239,8 @@
 			goto bail;
 		}
 	}
+unlock:
 	spin_unlock_irqrestore(&rq->lock, flags);
-
 bail:
 	return ret;
 }
@@ -270,38 +266,63 @@
 	struct ib_wc wc;
 	u64 sdata;
 	atomic64_t *maddr;
+	enum ib_wc_status send_status;
 
+	/*
+	 * Note that we check the responder QP state after
+	 * checking the requester's state.
+	 */
 	qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn);
-	if (!qp) {
-		dev->n_pkt_drops++;
-		return;
-	}
 
-again:
 	spin_lock_irqsave(&sqp->s_lock, flags);
 
-	if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_SEND_OK) ||
-	    sqp->s_rnr_timeout) {
-		spin_unlock_irqrestore(&sqp->s_lock, flags);
-		goto done;
-	}
+	/* Return if we are already busy processing a work request. */
+	if ((sqp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) ||
+	    !(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_OR_FLUSH_SEND))
+		goto unlock;
 
-	/* Get the next send request. */
-	if (sqp->s_last == sqp->s_head) {
-		/* Send work queue is empty. */
-		spin_unlock_irqrestore(&sqp->s_lock, flags);
-		goto done;
+	sqp->s_flags |= IPATH_S_BUSY;
+
+again:
+	if (sqp->s_last == sqp->s_head)
+		goto clr_busy;
+	wqe = get_swqe_ptr(sqp, sqp->s_last);
+
+	/* Return if it is not OK to start a new work reqeust. */
+	if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_NEXT_SEND_OK)) {
+		if (!(ib_ipath_state_ops[sqp->state] & IPATH_FLUSH_SEND))
+			goto clr_busy;
+		/* We are in the error state, flush the work request. */
+		send_status = IB_WC_WR_FLUSH_ERR;
+		goto flush_send;
 	}
 
 	/*
 	 * We can rely on the entry not changing without the s_lock
 	 * being held until we update s_last.
+	 * We increment s_cur to indicate s_last is in progress.
 	 */
-	wqe = get_swqe_ptr(sqp, sqp->s_last);
+	if (sqp->s_last == sqp->s_cur) {
+		if (++sqp->s_cur >= sqp->s_size)
+			sqp->s_cur = 0;
+	}
 	spin_unlock_irqrestore(&sqp->s_lock, flags);
 
-	wc.wc_flags = 0;
-	wc.imm_data = 0;
+	if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) {
+		dev->n_pkt_drops++;
+		/*
+		 * For RC, the requester would timeout and retry so
+		 * shortcut the timeouts and just signal too many retries.
+		 */
+		if (sqp->ibqp.qp_type == IB_QPT_RC)
+			send_status = IB_WC_RETRY_EXC_ERR;
+		else
+			send_status = IB_WC_SUCCESS;
+		goto serr;
+	}
+
+	memset(&wc, 0, sizeof wc);
+	send_status = IB_WC_SUCCESS;
 
 	sqp->s_sge.sge = wqe->sg_list[0];
 	sqp->s_sge.sg_list = wqe->sg_list + 1;
@@ -313,75 +334,33 @@
 		wc.imm_data = wqe->wr.ex.imm_data;
 		/* FALLTHROUGH */
 	case IB_WR_SEND:
-		if (!ipath_get_rwqe(qp, 0)) {
-		rnr_nak:
-			/* Handle RNR NAK */
-			if (qp->ibqp.qp_type == IB_QPT_UC)
-				goto send_comp;
-			if (sqp->s_rnr_retry == 0) {
-				wc.status = IB_WC_RNR_RETRY_EXC_ERR;
-				goto err;
-			}
-			if (sqp->s_rnr_retry_cnt < 7)
-				sqp->s_rnr_retry--;
-			dev->n_rnr_naks++;
-			sqp->s_rnr_timeout =
-				ib_ipath_rnr_table[qp->r_min_rnr_timer];
-			ipath_insert_rnr_queue(sqp);
-			goto done;
-		}
+		if (!ipath_get_rwqe(qp, 0))
+			goto rnr_nak;
 		break;
 
 	case IB_WR_RDMA_WRITE_WITH_IMM:
-		if (unlikely(!(qp->qp_access_flags &
-			       IB_ACCESS_REMOTE_WRITE))) {
-			wc.status = IB_WC_REM_INV_REQ_ERR;
-			goto err;
-		}
+		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE)))
+			goto inv_err;
 		wc.wc_flags = IB_WC_WITH_IMM;
 		wc.imm_data = wqe->wr.ex.imm_data;
 		if (!ipath_get_rwqe(qp, 1))
 			goto rnr_nak;
 		/* FALLTHROUGH */
 	case IB_WR_RDMA_WRITE:
-		if (unlikely(!(qp->qp_access_flags &
-			       IB_ACCESS_REMOTE_WRITE))) {
-			wc.status = IB_WC_REM_INV_REQ_ERR;
-			goto err;
-		}
+		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE)))
+			goto inv_err;
 		if (wqe->length == 0)
 			break;
 		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, wqe->length,
 					    wqe->wr.wr.rdma.remote_addr,
 					    wqe->wr.wr.rdma.rkey,
-					    IB_ACCESS_REMOTE_WRITE))) {
-		acc_err:
-			wc.status = IB_WC_REM_ACCESS_ERR;
-		err:
-			wc.wr_id = wqe->wr.wr_id;
-			wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-			wc.vendor_err = 0;
-			wc.byte_len = 0;
-			wc.qp = &sqp->ibqp;
-			wc.src_qp = sqp->remote_qpn;
-			wc.pkey_index = 0;
-			wc.slid = sqp->remote_ah_attr.dlid;
-			wc.sl = sqp->remote_ah_attr.sl;
-			wc.dlid_path_bits = 0;
-			wc.port_num = 0;
-			spin_lock_irqsave(&sqp->s_lock, flags);
-			ipath_sqerror_qp(sqp, &wc);
-			spin_unlock_irqrestore(&sqp->s_lock, flags);
-			goto done;
-		}
+					    IB_ACCESS_REMOTE_WRITE)))
+			goto acc_err;
 		break;
 
 	case IB_WR_RDMA_READ:
-		if (unlikely(!(qp->qp_access_flags &
-			       IB_ACCESS_REMOTE_READ))) {
-			wc.status = IB_WC_REM_INV_REQ_ERR;
-			goto err;
-		}
+		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ)))
+			goto inv_err;
 		if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
 					    wqe->wr.wr.rdma.remote_addr,
 					    wqe->wr.wr.rdma.rkey,
@@ -394,11 +373,8 @@
 
 	case IB_WR_ATOMIC_CMP_AND_SWP:
 	case IB_WR_ATOMIC_FETCH_AND_ADD:
-		if (unlikely(!(qp->qp_access_flags &
-			       IB_ACCESS_REMOTE_ATOMIC))) {
-			wc.status = IB_WC_REM_INV_REQ_ERR;
-			goto err;
-		}
+		if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC)))
+			goto inv_err;
 		if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
 					    wqe->wr.wr.atomic.remote_addr,
 					    wqe->wr.wr.atomic.rkey,
@@ -415,7 +391,8 @@
 		goto send_comp;
 
 	default:
-		goto done;
+		send_status = IB_WC_LOC_QP_OP_ERR;
+		goto serr;
 	}
 
 	sge = &sqp->s_sge.sge;
@@ -448,8 +425,7 @@
 		sqp->s_len -= len;
 	}
 
-	if (wqe->wr.opcode == IB_WR_RDMA_WRITE ||
-	    wqe->wr.opcode == IB_WR_RDMA_READ)
+	if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags))
 		goto send_comp;
 
 	if (wqe->wr.opcode == IB_WR_RDMA_WRITE_WITH_IMM)
@@ -458,32 +434,89 @@
 		wc.opcode = IB_WC_RECV;
 	wc.wr_id = qp->r_wr_id;
 	wc.status = IB_WC_SUCCESS;
-	wc.vendor_err = 0;
 	wc.byte_len = wqe->length;
 	wc.qp = &qp->ibqp;
 	wc.src_qp = qp->remote_qpn;
-	wc.pkey_index = 0;
 	wc.slid = qp->remote_ah_attr.dlid;
 	wc.sl = qp->remote_ah_attr.sl;
-	wc.dlid_path_bits = 0;
 	wc.port_num = 1;
 	/* Signal completion event if the solicited bit is set. */
 	ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
 		       wqe->wr.send_flags & IB_SEND_SOLICITED);
 
 send_comp:
+	spin_lock_irqsave(&sqp->s_lock, flags);
+flush_send:
 	sqp->s_rnr_retry = sqp->s_rnr_retry_cnt;
-	ipath_send_complete(sqp, wqe, IB_WC_SUCCESS);
+	ipath_send_complete(sqp, wqe, send_status);
 	goto again;
 
+rnr_nak:
+	/* Handle RNR NAK */
+	if (qp->ibqp.qp_type == IB_QPT_UC)
+		goto send_comp;
+	/*
+	 * Note: we don't need the s_lock held since the BUSY flag
+	 * makes this single threaded.
+	 */
+	if (sqp->s_rnr_retry == 0) {
+		send_status = IB_WC_RNR_RETRY_EXC_ERR;
+		goto serr;
+	}
+	if (sqp->s_rnr_retry_cnt < 7)
+		sqp->s_rnr_retry--;
+	spin_lock_irqsave(&sqp->s_lock, flags);
+	if (!(ib_ipath_state_ops[sqp->state] & IPATH_PROCESS_RECV_OK))
+		goto clr_busy;
+	sqp->s_flags |= IPATH_S_WAITING;
+	dev->n_rnr_naks++;
+	sqp->s_rnr_timeout = ib_ipath_rnr_table[qp->r_min_rnr_timer];
+	ipath_insert_rnr_queue(sqp);
+	goto clr_busy;
+
+inv_err:
+	send_status = IB_WC_REM_INV_REQ_ERR;
+	wc.status = IB_WC_LOC_QP_OP_ERR;
+	goto err;
+
+acc_err:
+	send_status = IB_WC_REM_ACCESS_ERR;
+	wc.status = IB_WC_LOC_PROT_ERR;
+err:
+	/* responder goes to error state */
+	ipath_rc_error(qp, wc.status);
+
+serr:
+	spin_lock_irqsave(&sqp->s_lock, flags);
+	ipath_send_complete(sqp, wqe, send_status);
+	if (sqp->ibqp.qp_type == IB_QPT_RC) {
+		int lastwqe = ipath_error_qp(sqp, IB_WC_WR_FLUSH_ERR);
+
+		sqp->s_flags &= ~IPATH_S_BUSY;
+		spin_unlock_irqrestore(&sqp->s_lock, flags);
+		if (lastwqe) {
+			struct ib_event ev;
+
+			ev.device = sqp->ibqp.device;
+			ev.element.qp = &sqp->ibqp;
+			ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
+			sqp->ibqp.event_handler(&ev, sqp->ibqp.qp_context);
+		}
+		goto done;
+	}
+clr_busy:
+	sqp->s_flags &= ~IPATH_S_BUSY;
+unlock:
+	spin_unlock_irqrestore(&sqp->s_lock, flags);
 done:
-	if (atomic_dec_and_test(&qp->refcount))
+	if (qp && atomic_dec_and_test(&qp->refcount))
 		wake_up(&qp->wait);
 }
 
-static void want_buffer(struct ipath_devdata *dd)
+static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp)
 {
-	if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA)) {
+	if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA) ||
+	    qp->ibqp.qp_type == IB_QPT_SMI) {
 		unsigned long flags;
 
 		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
@@ -501,26 +534,36 @@
  * @dev: the device we ran out of buffers on
  *
  * Called when we run out of PIO buffers.
+ * If we are now in the error state, return zero to flush the
+ * send work request.
  */
-static void ipath_no_bufs_available(struct ipath_qp *qp,
+static int ipath_no_bufs_available(struct ipath_qp *qp,
 				    struct ipath_ibdev *dev)
 {
 	unsigned long flags;
+	int ret = 1;
 
 	/*
 	 * Note that as soon as want_buffer() is called and
 	 * possibly before it returns, ipath_ib_piobufavail()
-	 * could be called.  If we are still in the tasklet function,
-	 * tasklet_hi_schedule() will not call us until the next time
-	 * tasklet_hi_schedule() is called.
-	 * We leave the busy flag set so that another post send doesn't
-	 * try to put the same QP on the piowait list again.
+	 * could be called. Therefore, put QP on the piowait list before
+	 * enabling the PIO avail interrupt.
 	 */
-	spin_lock_irqsave(&dev->pending_lock, flags);
-	list_add_tail(&qp->piowait, &dev->piowait);
-	spin_unlock_irqrestore(&dev->pending_lock, flags);
-	want_buffer(dev->dd);
-	dev->n_piowait++;
+	spin_lock_irqsave(&qp->s_lock, flags);
+	if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) {
+		dev->n_piowait++;
+		qp->s_flags |= IPATH_S_WAITING;
+		qp->s_flags &= ~IPATH_S_BUSY;
+		spin_lock(&dev->pending_lock);
+		if (list_empty(&qp->piowait))
+			list_add_tail(&qp->piowait, &dev->piowait);
+		spin_unlock(&dev->pending_lock);
+	} else
+		ret = 0;
+	spin_unlock_irqrestore(&qp->s_lock, flags);
+	if (ret)
+		want_buffer(dev->dd, qp);
+	return ret;
 }
 
 /**
@@ -596,15 +639,13 @@
 	struct ipath_qp *qp = (struct ipath_qp *)data;
 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
 	int (*make_req)(struct ipath_qp *qp);
-
-	if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy))
-		goto bail;
+	unsigned long flags;
 
 	if ((qp->ibqp.qp_type == IB_QPT_RC ||
 	     qp->ibqp.qp_type == IB_QPT_UC) &&
 	    qp->remote_ah_attr.dlid == dev->dd->ipath_lid) {
 		ipath_ruc_loopback(qp);
-		goto clear;
+		goto bail;
 	}
 
 	if (qp->ibqp.qp_type == IB_QPT_RC)
@@ -614,6 +655,19 @@
 	else
 	       make_req = ipath_make_ud_req;
 
+	spin_lock_irqsave(&qp->s_lock, flags);
+
+	/* Return if we are already busy processing a work request. */
+	if ((qp->s_flags & (IPATH_S_BUSY | IPATH_S_ANY_WAIT)) ||
+	    !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND)) {
+		spin_unlock_irqrestore(&qp->s_lock, flags);
+		goto bail;
+	}
+
+	qp->s_flags |= IPATH_S_BUSY;
+
+	spin_unlock_irqrestore(&qp->s_lock, flags);
+
 again:
 	/* Check for a constructed packet to be sent. */
 	if (qp->s_hdrwords != 0) {
@@ -623,8 +677,8 @@
 		 */
 		if (ipath_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords,
 				     qp->s_cur_sge, qp->s_cur_size)) {
-			ipath_no_bufs_available(qp, dev);
-			goto bail;
+			if (ipath_no_bufs_available(qp, dev))
+				goto bail;
 		}
 		dev->n_unicast_xmit++;
 		/* Record that we sent the packet and s_hdr is empty. */
@@ -633,16 +687,20 @@
 
 	if (make_req(qp))
 		goto again;
-clear:
-	clear_bit(IPATH_S_BUSY, &qp->s_busy);
+
 bail:;
 }
 
+/*
+ * This should be called with s_lock held.
+ */
 void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe,
 			 enum ib_wc_status status)
 {
-	unsigned long flags;
-	u32 last;
+	u32 old_last, last;
+
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_OR_FLUSH_SEND))
+		return;
 
 	/* See ch. 11.2.4.1 and 10.7.3.1 */
 	if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
@@ -650,27 +708,25 @@
 	    status != IB_WC_SUCCESS) {
 		struct ib_wc wc;
 
+		memset(&wc, 0, sizeof wc);
 		wc.wr_id = wqe->wr.wr_id;
 		wc.status = status;
 		wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-		wc.vendor_err = 0;
-		wc.byte_len = wqe->length;
-		wc.imm_data = 0;
 		wc.qp = &qp->ibqp;
-		wc.src_qp = 0;
-		wc.wc_flags = 0;
-		wc.pkey_index = 0;
-		wc.slid = 0;
-		wc.sl = 0;
-		wc.dlid_path_bits = 0;
-		wc.port_num = 0;
-		ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0);
+		if (status == IB_WC_SUCCESS)
+			wc.byte_len = wqe->length;
+		ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc,
+			       status != IB_WC_SUCCESS);
 	}
 
-	spin_lock_irqsave(&qp->s_lock, flags);
-	last = qp->s_last;
+	old_last = last = qp->s_last;
 	if (++last >= qp->s_size)
 		last = 0;
 	qp->s_last = last;
-	spin_unlock_irqrestore(&qp->s_lock, flags);
+	if (qp->s_cur == old_last)
+		qp->s_cur = last;
+	if (qp->s_tail == old_last)
+		qp->s_tail = last;
+	if (qp->state == IB_QPS_SQD && last == qp->s_cur)
+		qp->s_draining = 0;
 }
diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c
index 1974df7..3697449 100644
--- a/drivers/infiniband/hw/ipath/ipath_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_sdma.c
@@ -308,13 +308,15 @@
 		spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
 
 		/*
-		 * Don't restart sdma here. Wait until link is up to ACTIVE.
-		 * VL15 MADs used to bring the link up use PIO, and multiple
-		 * link transitions otherwise cause the sdma engine to be
+		 * Don't restart sdma here (with the exception
+		 * below). Wait until link is up to ACTIVE.  VL15 MADs
+		 * used to bring the link up use PIO, and multiple link
+		 * transitions otherwise cause the sdma engine to be
 		 * stopped and started multiple times.
-		 * The disable is done here, including the shadow, so the
-		 * state is kept consistent.
-		 * See ipath_restart_sdma() for the actual starting of sdma.
+		 * The disable is done here, including the shadow,
+		 * so the state is kept consistent.
+		 * See ipath_restart_sdma() for the actual starting
+		 * of sdma.
 		 */
 		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
 		dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE;
@@ -326,6 +328,13 @@
 		/* make sure I see next message */
 		dd->ipath_sdma_abort_jiffies = 0;
 
+		/*
+		 * Not everything that takes SDMA offline is a link
+		 * status change.  If the link was up, restart SDMA.
+		 */
+		if (dd->ipath_flags & IPATH_LINKACTIVE)
+			ipath_restart_sdma(dd);
+
 		goto done;
 	}
 
@@ -427,7 +436,12 @@
 		goto done;
 	}
 
-	dd->ipath_sdma_status = 0;
+	/*
+	 * Set initial status as if we had been up, then gone down.
+	 * This lets initial start on transition to ACTIVE be the
+	 * same as restart after link flap.
+	 */
+	dd->ipath_sdma_status = IPATH_SDMA_ABORT_ABORTED;
 	dd->ipath_sdma_abort_jiffies = 0;
 	dd->ipath_sdma_generation = 0;
 	dd->ipath_sdma_descq_tail = 0;
@@ -449,16 +463,19 @@
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmaheadaddr,
 			 dd->ipath_sdma_head_phys);
 
-	/* Reserve all the former "kernel" piobufs */
-	n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - dd->ipath_pioreserved;
-	for (i = dd->ipath_lastport_piobuf; i < n; ++i) {
+	/*
+	 * Reserve all the former "kernel" piobufs, using high number range
+	 * so we get as many 4K buffers as possible
+	 */
+	n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k;
+	i = dd->ipath_lastport_piobuf + dd->ipath_pioreserved;
+	ipath_chg_pioavailkernel(dd, i, n - i , 0);
+	for (; i < n; ++i) {
 		unsigned word = i / 64;
 		unsigned bit = i & 63;
 		BUG_ON(word >= 3);
 		senddmabufmask[word] |= 1ULL << bit;
 	}
-	ipath_chg_pioavailkernel(dd, dd->ipath_lastport_piobuf,
-		n - dd->ipath_lastport_piobuf, 0);
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask0,
 			 senddmabufmask[0]);
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask1,
@@ -615,6 +632,9 @@
 	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
 	spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
 
+	/* notify upper layers */
+	ipath_ib_piobufavail(dd->verbs_dev);
+
 bail:
 	return;
 }
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
index bfe8926..7fd18e8 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
+ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -47,14 +47,30 @@
 {
 	struct ipath_other_headers *ohdr;
 	struct ipath_swqe *wqe;
+	unsigned long flags;
 	u32 hwords;
 	u32 bth0;
 	u32 len;
 	u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu);
 	int ret = 0;
 
-	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK))
+	spin_lock_irqsave(&qp->s_lock, flags);
+
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) {
+		if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
+			goto bail;
+		/* We are in the error state, flush the work request. */
+		if (qp->s_last == qp->s_head)
+			goto bail;
+		/* If DMAs are in progress, we can't flush immediately. */
+		if (atomic_read(&qp->s_dma_busy)) {
+			qp->s_flags |= IPATH_S_WAIT_DMA;
+			goto bail;
+		}
+		wqe = get_swqe_ptr(qp, qp->s_last);
+		ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
 		goto done;
+	}
 
 	ohdr = &qp->s_hdr.u.oth;
 	if (qp->remote_ah_attr.ah_flags & IB_AH_GRH)
@@ -69,9 +85,12 @@
 	qp->s_wqe = NULL;
 	switch (qp->s_state) {
 	default:
+		if (!(ib_ipath_state_ops[qp->state] &
+		    IPATH_PROCESS_NEXT_SEND_OK))
+			goto bail;
 		/* Check if send work queue is empty. */
 		if (qp->s_cur == qp->s_head)
-			goto done;
+			goto bail;
 		/*
 		 * Start a new request.
 		 */
@@ -134,7 +153,7 @@
 			break;
 
 		default:
-			goto done;
+			goto bail;
 		}
 		break;
 
@@ -194,9 +213,14 @@
 	ipath_make_ruc_header(to_idev(qp->ibqp.device),
 			      qp, ohdr, bth0 | (qp->s_state << 24),
 			      qp->s_next_psn++ & IPATH_PSN_MASK);
-	ret = 1;
-
 done:
+	ret = 1;
+	goto unlock;
+
+bail:
+	qp->s_flags &= ~IPATH_S_BUSY;
+unlock:
+	spin_unlock_irqrestore(&qp->s_lock, flags);
 	return ret;
 }
 
@@ -258,8 +282,7 @@
 	 */
 	opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
 
-	wc.imm_data = 0;
-	wc.wc_flags = 0;
+	memset(&wc, 0, sizeof wc);
 
 	/* Compare the PSN verses the expected PSN. */
 	if (unlikely(ipath_cmp24(psn, qp->r_psn) != 0)) {
@@ -322,8 +345,8 @@
 	case OP(SEND_ONLY):
 	case OP(SEND_ONLY_WITH_IMMEDIATE):
 	send_first:
-		if (qp->r_reuse_sge) {
-			qp->r_reuse_sge = 0;
+		if (qp->r_flags & IPATH_R_REUSE_SGE) {
+			qp->r_flags &= ~IPATH_R_REUSE_SGE;
 			qp->r_sge = qp->s_rdma_read_sge;
 		} else if (!ipath_get_rwqe(qp, 0)) {
 			dev->n_pkt_drops++;
@@ -340,13 +363,13 @@
 	case OP(SEND_MIDDLE):
 		/* Check for invalid length PMTU or posted rwqe len. */
 		if (unlikely(tlen != (hdrsize + pmtu + 4))) {
-			qp->r_reuse_sge = 1;
+			qp->r_flags |= IPATH_R_REUSE_SGE;
 			dev->n_pkt_drops++;
 			goto done;
 		}
 		qp->r_rcv_len += pmtu;
 		if (unlikely(qp->r_rcv_len > qp->r_len)) {
-			qp->r_reuse_sge = 1;
+			qp->r_flags |= IPATH_R_REUSE_SGE;
 			dev->n_pkt_drops++;
 			goto done;
 		}
@@ -372,7 +395,7 @@
 		/* Check for invalid length. */
 		/* XXX LAST len should be >= 1 */
 		if (unlikely(tlen < (hdrsize + pad + 4))) {
-			qp->r_reuse_sge = 1;
+			qp->r_flags |= IPATH_R_REUSE_SGE;
 			dev->n_pkt_drops++;
 			goto done;
 		}
@@ -380,7 +403,7 @@
 		tlen -= (hdrsize + pad + 4);
 		wc.byte_len = tlen + qp->r_rcv_len;
 		if (unlikely(wc.byte_len > qp->r_len)) {
-			qp->r_reuse_sge = 1;
+			qp->r_flags |= IPATH_R_REUSE_SGE;
 			dev->n_pkt_drops++;
 			goto done;
 		}
@@ -390,14 +413,10 @@
 		wc.wr_id = qp->r_wr_id;
 		wc.status = IB_WC_SUCCESS;
 		wc.opcode = IB_WC_RECV;
-		wc.vendor_err = 0;
 		wc.qp = &qp->ibqp;
 		wc.src_qp = qp->remote_qpn;
-		wc.pkey_index = 0;
 		wc.slid = qp->remote_ah_attr.dlid;
 		wc.sl = qp->remote_ah_attr.sl;
-		wc.dlid_path_bits = 0;
-		wc.port_num = 0;
 		/* Signal completion event if the solicited bit is set. */
 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
 			       (ohdr->bth[0] &
@@ -488,8 +507,8 @@
 			dev->n_pkt_drops++;
 			goto done;
 		}
-		if (qp->r_reuse_sge)
-			qp->r_reuse_sge = 0;
+		if (qp->r_flags & IPATH_R_REUSE_SGE)
+			qp->r_flags &= ~IPATH_R_REUSE_SGE;
 		else if (!ipath_get_rwqe(qp, 1)) {
 			dev->n_pkt_drops++;
 			goto done;
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 8b6a261..77ca8ca 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -65,9 +65,9 @@
 	u32 length;
 
 	qp = ipath_lookup_qpn(&dev->qp_table, swqe->wr.wr.ud.remote_qpn);
-	if (!qp) {
+	if (!qp || !(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_RECV_OK)) {
 		dev->n_pkt_drops++;
-		goto send_comp;
+		goto done;
 	}
 
 	rsge.sg_list = NULL;
@@ -91,14 +91,12 @@
 	 * present on the wire.
 	 */
 	length = swqe->length;
+	memset(&wc, 0, sizeof wc);
 	wc.byte_len = length + sizeof(struct ib_grh);
 
 	if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) {
 		wc.wc_flags = IB_WC_WITH_IMM;
 		wc.imm_data = swqe->wr.ex.imm_data;
-	} else {
-		wc.wc_flags = 0;
-		wc.imm_data = 0;
 	}
 
 	/*
@@ -229,7 +227,6 @@
 	}
 	wc.status = IB_WC_SUCCESS;
 	wc.opcode = IB_WC_RECV;
-	wc.vendor_err = 0;
 	wc.qp = &qp->ibqp;
 	wc.src_qp = sqp->ibqp.qp_num;
 	/* XXX do we know which pkey matched? Only needed for GSI. */
@@ -248,8 +245,7 @@
 	kfree(rsge.sg_list);
 	if (atomic_dec_and_test(&qp->refcount))
 		wake_up(&qp->wait);
-send_comp:
-	ipath_send_complete(sqp, swqe, IB_WC_SUCCESS);
+done:;
 }
 
 /**
@@ -264,6 +260,7 @@
 	struct ipath_other_headers *ohdr;
 	struct ib_ah_attr *ah_attr;
 	struct ipath_swqe *wqe;
+	unsigned long flags;
 	u32 nwords;
 	u32 extra_bytes;
 	u32 bth0;
@@ -271,13 +268,30 @@
 	u16 lid;
 	int ret = 0;
 
-	if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)))
-		goto bail;
+	spin_lock_irqsave(&qp->s_lock, flags);
+
+	if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_NEXT_SEND_OK)) {
+		if (!(ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND))
+			goto bail;
+		/* We are in the error state, flush the work request. */
+		if (qp->s_last == qp->s_head)
+			goto bail;
+		/* If DMAs are in progress, we can't flush immediately. */
+		if (atomic_read(&qp->s_dma_busy)) {
+			qp->s_flags |= IPATH_S_WAIT_DMA;
+			goto bail;
+		}
+		wqe = get_swqe_ptr(qp, qp->s_last);
+		ipath_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
+		goto done;
+	}
 
 	if (qp->s_cur == qp->s_head)
 		goto bail;
 
 	wqe = get_swqe_ptr(qp, qp->s_cur);
+	if (++qp->s_cur >= qp->s_size)
+		qp->s_cur = 0;
 
 	/* Construct the header. */
 	ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
@@ -288,10 +302,23 @@
 			dev->n_unicast_xmit++;
 	} else {
 		dev->n_unicast_xmit++;
-		lid = ah_attr->dlid &
-			~((1 << dev->dd->ipath_lmc) - 1);
+		lid = ah_attr->dlid & ~((1 << dev->dd->ipath_lmc) - 1);
 		if (unlikely(lid == dev->dd->ipath_lid)) {
+			/*
+			 * If DMAs are in progress, we can't generate
+			 * a completion for the loopback packet since
+			 * it would be out of order.
+			 * XXX Instead of waiting, we could queue a
+			 * zero length descriptor so we get a callback.
+			 */
+			if (atomic_read(&qp->s_dma_busy)) {
+				qp->s_flags |= IPATH_S_WAIT_DMA;
+				goto bail;
+			}
+			spin_unlock_irqrestore(&qp->s_lock, flags);
 			ipath_ud_loopback(qp, wqe);
+			spin_lock_irqsave(&qp->s_lock, flags);
+			ipath_send_complete(qp, wqe, IB_WC_SUCCESS);
 			goto done;
 		}
 	}
@@ -368,11 +395,13 @@
 	ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num);
 
 done:
-	if (++qp->s_cur >= qp->s_size)
-		qp->s_cur = 0;
 	ret = 1;
+	goto unlock;
 
 bail:
+	qp->s_flags &= ~IPATH_S_BUSY;
+unlock:
+	spin_unlock_irqrestore(&qp->s_lock, flags);
 	return ret;
 }
 
@@ -506,8 +535,8 @@
 	/*
 	 * Get the next work request entry to find where to put the data.
 	 */
-	if (qp->r_reuse_sge)
-		qp->r_reuse_sge = 0;
+	if (qp->r_flags & IPATH_R_REUSE_SGE)
+		qp->r_flags &= ~IPATH_R_REUSE_SGE;
 	else if (!ipath_get_rwqe(qp, 0)) {
 		/*
 		 * Count VL15 packets dropped due to no receive buffer.
@@ -523,7 +552,7 @@
 	}
 	/* Silently drop packets which are too big. */
 	if (wc.byte_len > qp->r_len) {
-		qp->r_reuse_sge = 1;
+		qp->r_flags |= IPATH_R_REUSE_SGE;
 		dev->n_pkt_drops++;
 		goto bail;
 	}
@@ -535,7 +564,8 @@
 		ipath_skip_sge(&qp->r_sge, sizeof(struct ib_grh));
 	ipath_copy_sge(&qp->r_sge, data,
 		       wc.byte_len - sizeof(struct ib_grh));
-	qp->r_wrid_valid = 0;
+	if (!test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags))
+		goto bail;
 	wc.wr_id = qp->r_wr_id;
 	wc.status = IB_WC_SUCCESS;
 	wc.opcode = IB_WC_RECV;
diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.h b/drivers/infiniband/hw/ipath/ipath_user_sdma.h
index e70946c..fc76316 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_sdma.h
+++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.h
@@ -45,8 +45,6 @@
 int ipath_user_sdma_make_progress(struct ipath_devdata *dd,
 				  struct ipath_user_sdma_queue *pq);
 
-int ipath_user_sdma_pkt_sent(const struct ipath_user_sdma_queue *pq,
-			     u32 counter);
 void ipath_user_sdma_queue_drain(struct ipath_devdata *dd,
 				 struct ipath_user_sdma_queue *pq);
 
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index e63927c..e0ec540 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -111,16 +111,24 @@
 module_param_named(disable_sma, ib_ipath_disable_sma, uint, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(disable_sma, "Disable the SMA");
 
+/*
+ * Note that it is OK to post send work requests in the SQE and ERR
+ * states; ipath_do_send() will process them and generate error
+ * completions as per IB 1.2 C10-96.
+ */
 const int ib_ipath_state_ops[IB_QPS_ERR + 1] = {
 	[IB_QPS_RESET] = 0,
 	[IB_QPS_INIT] = IPATH_POST_RECV_OK,
 	[IB_QPS_RTR] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK,
 	[IB_QPS_RTS] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK |
-	    IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK,
+	    IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK |
+	    IPATH_PROCESS_NEXT_SEND_OK,
 	[IB_QPS_SQD] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK |
-	    IPATH_POST_SEND_OK,
-	[IB_QPS_SQE] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK,
-	[IB_QPS_ERR] = 0,
+	    IPATH_POST_SEND_OK | IPATH_PROCESS_SEND_OK,
+	[IB_QPS_SQE] = IPATH_POST_RECV_OK | IPATH_PROCESS_RECV_OK |
+	    IPATH_POST_SEND_OK | IPATH_FLUSH_SEND,
+	[IB_QPS_ERR] = IPATH_POST_RECV_OK | IPATH_FLUSH_RECV |
+	    IPATH_POST_SEND_OK | IPATH_FLUSH_SEND,
 };
 
 struct ipath_ucontext {
@@ -230,18 +238,6 @@
 	}
 }
 
-static void ipath_flush_wqe(struct ipath_qp *qp, struct ib_send_wr *wr)
-{
-	struct ib_wc wc;
-
-	memset(&wc, 0, sizeof(wc));
-	wc.wr_id = wr->wr_id;
-	wc.status = IB_WC_WR_FLUSH_ERR;
-	wc.opcode = ib_ipath_wc_opcode[wr->opcode];
-	wc.qp = &qp->ibqp;
-	ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
-}
-
 /*
  * Count the number of DMA descriptors needed to send length bytes of data.
  * Don't modify the ipath_sge_state to get the count.
@@ -347,14 +343,8 @@
 	spin_lock_irqsave(&qp->s_lock, flags);
 
 	/* Check that state is OK to post send. */
-	if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK))) {
-		if (qp->state != IB_QPS_SQE && qp->state != IB_QPS_ERR)
-			goto bail_inval;
-		/* C10-96 says generate a flushed completion entry. */
-		ipath_flush_wqe(qp, wr);
-		ret = 0;
-		goto bail;
-	}
+	if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK)))
+		goto bail_inval;
 
 	/* IB spec says that num_sge == 0 is OK. */
 	if (wr->num_sge > qp->s_max_sge)
@@ -396,7 +386,6 @@
 
 	wqe = get_swqe_ptr(qp, qp->s_head);
 	wqe->wr = *wr;
-	wqe->ssn = qp->s_ssn++;
 	wqe->length = 0;
 	if (wr->num_sge) {
 		acc = wr->opcode >= IB_WR_RDMA_READ ?
@@ -422,6 +411,7 @@
 			goto bail_inval;
 	} else if (wqe->length > to_idev(qp->ibqp.device)->dd->ipath_ibmtu)
 		goto bail_inval;
+	wqe->ssn = qp->s_ssn++;
 	qp->s_head = next;
 
 	ret = 0;
@@ -677,6 +667,7 @@
 static void ipath_ib_timer(struct ipath_ibdev *dev)
 {
 	struct ipath_qp *resend = NULL;
+	struct ipath_qp *rnr = NULL;
 	struct list_head *last;
 	struct ipath_qp *qp;
 	unsigned long flags;
@@ -703,7 +694,9 @@
 		if (--qp->s_rnr_timeout == 0) {
 			do {
 				list_del_init(&qp->timerwait);
-				tasklet_hi_schedule(&qp->s_task);
+				qp->timer_next = rnr;
+				rnr = qp;
+				atomic_inc(&qp->refcount);
 				if (list_empty(last))
 					break;
 				qp = list_entry(last->next, struct ipath_qp,
@@ -743,13 +736,15 @@
 	spin_unlock_irqrestore(&dev->pending_lock, flags);
 
 	/* XXX What if timer fires again while this is running? */
-	for (qp = resend; qp != NULL; qp = qp->timer_next) {
-		struct ib_wc wc;
+	while (resend != NULL) {
+		qp = resend;
+		resend = qp->timer_next;
 
 		spin_lock_irqsave(&qp->s_lock, flags);
-		if (qp->s_last != qp->s_tail && qp->state == IB_QPS_RTS) {
+		if (qp->s_last != qp->s_tail &&
+		    ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) {
 			dev->n_timeouts++;
-			ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+			ipath_restart_rc(qp, qp->s_last_psn + 1);
 		}
 		spin_unlock_irqrestore(&qp->s_lock, flags);
 
@@ -757,6 +752,19 @@
 		if (atomic_dec_and_test(&qp->refcount))
 			wake_up(&qp->wait);
 	}
+	while (rnr != NULL) {
+		qp = rnr;
+		rnr = qp->timer_next;
+
+		spin_lock_irqsave(&qp->s_lock, flags);
+		if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)
+			ipath_schedule_send(qp);
+		spin_unlock_irqrestore(&qp->s_lock, flags);
+
+		/* Notify ipath_destroy_qp() if it is waiting. */
+		if (atomic_dec_and_test(&qp->refcount))
+			wake_up(&qp->wait);
+	}
 }
 
 static void update_sge(struct ipath_sge_state *ss, u32 length)
@@ -1012,13 +1020,24 @@
 	struct ipath_verbs_txreq *tx = cookie;
 	struct ipath_qp *qp = tx->qp;
 	struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
+	unsigned int flags;
+	enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ?
+		IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR;
 
-	/* Generate a completion queue entry if needed */
-	if (qp->ibqp.qp_type != IB_QPT_RC && tx->wqe) {
-		enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ?
-			IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR;
-
+	if (atomic_dec_and_test(&qp->s_dma_busy)) {
+		spin_lock_irqsave(&qp->s_lock, flags);
+		if (tx->wqe)
+			ipath_send_complete(qp, tx->wqe, ibs);
+		if ((ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND &&
+		     qp->s_last != qp->s_head) ||
+		    (qp->s_flags & IPATH_S_WAIT_DMA))
+			ipath_schedule_send(qp);
+		spin_unlock_irqrestore(&qp->s_lock, flags);
+		wake_up(&qp->wait_dma);
+	} else if (tx->wqe) {
+		spin_lock_irqsave(&qp->s_lock, flags);
 		ipath_send_complete(qp, tx->wqe, ibs);
+		spin_unlock_irqrestore(&qp->s_lock, flags);
 	}
 
 	if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_FREEBUF)
@@ -1029,6 +1048,21 @@
 		wake_up(&qp->wait);
 }
 
+static void decrement_dma_busy(struct ipath_qp *qp)
+{
+	unsigned int flags;
+
+	if (atomic_dec_and_test(&qp->s_dma_busy)) {
+		spin_lock_irqsave(&qp->s_lock, flags);
+		if ((ib_ipath_state_ops[qp->state] & IPATH_FLUSH_SEND &&
+		     qp->s_last != qp->s_head) ||
+		    (qp->s_flags & IPATH_S_WAIT_DMA))
+			ipath_schedule_send(qp);
+		spin_unlock_irqrestore(&qp->s_lock, flags);
+		wake_up(&qp->wait_dma);
+	}
+}
+
 /*
  * Compute the number of clock cycles of delay before sending the next packet.
  * The multipliers reflect the number of clocks for the fastest rate so
@@ -1067,9 +1101,12 @@
 	if (tx) {
 		qp->s_tx = NULL;
 		/* resend previously constructed packet */
+		atomic_inc(&qp->s_dma_busy);
 		ret = ipath_sdma_verbs_send(dd, tx->ss, tx->len, tx);
-		if (ret)
+		if (ret) {
 			qp->s_tx = tx;
+			decrement_dma_busy(qp);
+		}
 		goto bail;
 	}
 
@@ -1120,12 +1157,14 @@
 		tx->txreq.sg_count = ndesc;
 		tx->map_len = (hdrwords + 2) << 2;
 		tx->txreq.map_addr = &tx->hdr;
+		atomic_inc(&qp->s_dma_busy);
 		ret = ipath_sdma_verbs_send(dd, ss, dwords, tx);
 		if (ret) {
 			/* save ss and length in dwords */
 			tx->ss = ss;
 			tx->len = dwords;
 			qp->s_tx = tx;
+			decrement_dma_busy(qp);
 		}
 		goto bail;
 	}
@@ -1146,6 +1185,7 @@
 	memcpy(piobuf, hdr, hdrwords << 2);
 	ipath_copy_from_sge(piobuf + hdrwords, ss, len);
 
+	atomic_inc(&qp->s_dma_busy);
 	ret = ipath_sdma_verbs_send(dd, NULL, 0, tx);
 	/*
 	 * If we couldn't queue the DMA request, save the info
@@ -1156,6 +1196,7 @@
 		tx->ss = NULL;
 		tx->len = 0;
 		qp->s_tx = tx;
+		decrement_dma_busy(qp);
 	}
 	dev->n_unaligned++;
 	goto bail;
@@ -1179,6 +1220,7 @@
 	unsigned flush_wc;
 	u32 control;
 	int ret;
+	unsigned int flags;
 
 	piobuf = ipath_getpiobuf(dd, plen, NULL);
 	if (unlikely(piobuf == NULL)) {
@@ -1249,8 +1291,11 @@
 	}
 	copy_io(piobuf, ss, len, flush_wc);
 done:
-	if (qp->s_wqe)
+	if (qp->s_wqe) {
+		spin_lock_irqsave(&qp->s_lock, flags);
 		ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS);
+		spin_unlock_irqrestore(&qp->s_lock, flags);
+	}
 	ret = 0;
 bail:
 	return ret;
@@ -1283,19 +1328,12 @@
 	 * can defer SDMA restart until link goes ACTIVE without
 	 * worrying about just how we got there.
 	 */
-	if (qp->ibqp.qp_type == IB_QPT_SMI)
+	if (qp->ibqp.qp_type == IB_QPT_SMI ||
+	    !(dd->ipath_flags & IPATH_HAS_SEND_DMA))
 		ret = ipath_verbs_send_pio(qp, hdr, hdrwords, ss, len,
 					   plen, dwords);
-	/* All non-VL15 packets are dropped if link is not ACTIVE */
-	else if (!(dd->ipath_flags & IPATH_LINKACTIVE)) {
-		if (qp->s_wqe)
-			ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS);
-		ret = 0;
-	} else if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
-		ret = ipath_verbs_send_dma(qp, hdr, hdrwords, ss, len,
-					   plen, dwords);
 	else
-		ret = ipath_verbs_send_pio(qp, hdr, hdrwords, ss, len,
+		ret = ipath_verbs_send_dma(qp, hdr, hdrwords, ss, len,
 					   plen, dwords);
 
 	return ret;
@@ -1403,27 +1441,46 @@
  * This is called from ipath_intr() at interrupt level when a PIO buffer is
  * available after ipath_verbs_send() returned an error that no buffers were
  * available.  Return 1 if we consumed all the PIO buffers and we still have
- * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and
+ * QPs waiting for buffers (for now, just restart the send tasklet and
  * return zero).
  */
 int ipath_ib_piobufavail(struct ipath_ibdev *dev)
 {
+	struct list_head *list;
+	struct ipath_qp *qplist;
 	struct ipath_qp *qp;
 	unsigned long flags;
 
 	if (dev == NULL)
 		goto bail;
 
+	list = &dev->piowait;
+	qplist = NULL;
+
 	spin_lock_irqsave(&dev->pending_lock, flags);
-	while (!list_empty(&dev->piowait)) {
-		qp = list_entry(dev->piowait.next, struct ipath_qp,
-				piowait);
+	while (!list_empty(list)) {
+		qp = list_entry(list->next, struct ipath_qp, piowait);
 		list_del_init(&qp->piowait);
-		clear_bit(IPATH_S_BUSY, &qp->s_busy);
-		tasklet_hi_schedule(&qp->s_task);
+		qp->pio_next = qplist;
+		qplist = qp;
+		atomic_inc(&qp->refcount);
 	}
 	spin_unlock_irqrestore(&dev->pending_lock, flags);
 
+	while (qplist != NULL) {
+		qp = qplist;
+		qplist = qp->pio_next;
+
+		spin_lock_irqsave(&qp->s_lock, flags);
+		if (ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)
+			ipath_schedule_send(qp);
+		spin_unlock_irqrestore(&qp->s_lock, flags);
+
+		/* Notify ipath_destroy_qp() if it is waiting. */
+		if (atomic_dec_and_test(&qp->refcount))
+			wake_up(&qp->wait);
+	}
+
 bail:
 	return 0;
 }
@@ -2145,11 +2202,12 @@
 void ipath_unregister_ib_device(struct ipath_ibdev *dev)
 {
 	struct ib_device *ibdev = &dev->ibdev;
-
-	disable_timer(dev->dd);
+	u32 qps_inuse;
 
 	ib_unregister_device(ibdev);
 
+	disable_timer(dev->dd);
+
 	if (!list_empty(&dev->pending[0]) ||
 	    !list_empty(&dev->pending[1]) ||
 	    !list_empty(&dev->pending[2]))
@@ -2164,7 +2222,10 @@
 	 * Note that ipath_unregister_ib_device() can be called before all
 	 * the QPs are destroyed!
 	 */
-	ipath_free_all_qps(&dev->qp_table);
+	qps_inuse = ipath_free_all_qps(&dev->qp_table);
+	if (qps_inuse)
+		ipath_dev_err(dev->dd, "QP memory leak! %u still in use\n",
+			qps_inuse);
 	kfree(dev->qp_table.table);
 	kfree(dev->lk_table.table);
 	kfree(dev->txreq_bufs);
@@ -2215,17 +2276,14 @@
 		      "RC OTH NAKs %d\n"
 		      "RC timeouts %d\n"
 		      "RC RDMA dup %d\n"
-		      "RC stalls   %d\n"
 		      "piobuf wait %d\n"
-		      "no piobuf   %d\n"
 		      "unaligned   %d\n"
 		      "PKT drops   %d\n"
 		      "WQE errs    %d\n",
 		      dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks,
 		      dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks,
 		      dev->n_other_naks, dev->n_timeouts,
-		      dev->n_rdma_dup_busy, dev->n_rc_stalls, dev->n_piowait,
-		      dev->n_no_piobuf, dev->n_unaligned,
+		      dev->n_rdma_dup_busy, dev->n_piowait, dev->n_unaligned,
 		      dev->n_pkt_drops, dev->n_wqe_errs);
 	for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) {
 		const struct ipath_opcode_stats *si = &dev->opstats[i];
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 6514aa8..9d12ae8 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -74,6 +74,11 @@
 #define IPATH_POST_RECV_OK		0x02
 #define IPATH_PROCESS_RECV_OK		0x04
 #define IPATH_PROCESS_SEND_OK		0x08
+#define IPATH_PROCESS_NEXT_SEND_OK	0x10
+#define IPATH_FLUSH_SEND		0x20
+#define IPATH_FLUSH_RECV		0x40
+#define IPATH_PROCESS_OR_FLUSH_SEND \
+	(IPATH_PROCESS_SEND_OK | IPATH_FLUSH_SEND)
 
 /* IB Performance Manager status values */
 #define IB_PMA_SAMPLE_STATUS_DONE	0x00
@@ -353,12 +358,14 @@
 	struct ib_qp ibqp;
 	struct ipath_qp *next;		/* link list for QPN hash table */
 	struct ipath_qp *timer_next;	/* link list for ipath_ib_timer() */
+	struct ipath_qp *pio_next;	/* link for ipath_ib_piobufavail() */
 	struct list_head piowait;	/* link for wait PIO buf */
 	struct list_head timerwait;	/* link for waiting for timeouts */
 	struct ib_ah_attr remote_ah_attr;
 	struct ipath_ib_header s_hdr;	/* next packet header to send */
 	atomic_t refcount;
 	wait_queue_head_t wait;
+	wait_queue_head_t wait_dma;
 	struct tasklet_struct s_task;
 	struct ipath_mmap_info *ip;
 	struct ipath_sge_state *s_cur_sge;
@@ -369,7 +376,7 @@
 	struct ipath_sge_state s_rdma_read_sge;
 	struct ipath_sge_state r_sge;	/* current receive data */
 	spinlock_t s_lock;
-	unsigned long s_busy;
+	atomic_t s_dma_busy;
 	u16 s_pkt_delay;
 	u16 s_hdrwords;		/* size of s_hdr in 32 bit words */
 	u32 s_cur_size;		/* size of send packet in bytes */
@@ -383,6 +390,7 @@
 	u32 s_rnr_timeout;	/* number of milliseconds for RNR timeout */
 	u32 r_ack_psn;		/* PSN for next ACK or atomic ACK */
 	u64 r_wr_id;		/* ID for current receive WQE */
+	unsigned long r_aflags;
 	u32 r_len;		/* total length of r_sge */
 	u32 r_rcv_len;		/* receive data len processed */
 	u32 r_psn;		/* expected rcv packet sequence number */
@@ -394,8 +402,7 @@
 	u8 r_state;		/* opcode of last packet received */
 	u8 r_nak_state;		/* non-zero if NAK is pending */
 	u8 r_min_rnr_timer;	/* retry timeout value for RNR NAKs */
-	u8 r_reuse_sge;		/* for UC receive errors */
-	u8 r_wrid_valid;	/* r_wrid set but CQ entry not yet made */
+	u8 r_flags;
 	u8 r_max_rd_atomic;	/* max number of RDMA read/atomic to receive */
 	u8 r_head_ack_queue;	/* index into s_ack_queue[] */
 	u8 qp_access_flags;
@@ -404,13 +411,13 @@
 	u8 s_rnr_retry_cnt;
 	u8 s_retry;		/* requester retry counter */
 	u8 s_rnr_retry;		/* requester RNR retry counter */
-	u8 s_wait_credit;	/* limit number of unacked packets sent */
 	u8 s_pkey_index;	/* PKEY index to use */
 	u8 s_max_rd_atomic;	/* max number of RDMA read/atomic to send */
 	u8 s_num_rd_atomic;	/* number of RDMA read/atomic pending */
 	u8 s_tail_ack_queue;	/* index into s_ack_queue[] */
 	u8 s_flags;
 	u8 s_dmult;
+	u8 s_draining;
 	u8 timeout;		/* Timeout for this QP */
 	enum ib_mtu path_mtu;
 	u32 remote_qpn;
@@ -428,16 +435,40 @@
 	struct ipath_sge r_sg_list[0];	/* verified SGEs */
 };
 
-/* Bit definition for s_busy. */
-#define IPATH_S_BUSY		0
+/*
+ * Atomic bit definitions for r_aflags.
+ */
+#define IPATH_R_WRID_VALID	0
+
+/*
+ * Bit definitions for r_flags.
+ */
+#define IPATH_R_REUSE_SGE	0x01
+#define IPATH_R_RDMAR_SEQ	0x02
 
 /*
  * Bit definitions for s_flags.
+ *
+ * IPATH_S_FENCE_PENDING - waiting for all prior RDMA read or atomic SWQEs
+ *			   before processing the next SWQE
+ * IPATH_S_RDMAR_PENDING - waiting for any RDMA read or atomic SWQEs
+ *			   before processing the next SWQE
+ * IPATH_S_WAITING - waiting for RNR timeout or send buffer available.
+ * IPATH_S_WAIT_SSN_CREDIT - waiting for RC credits to process next SWQE
+ * IPATH_S_WAIT_DMA - waiting for send DMA queue to drain before generating
+ *		      next send completion entry not via send DMA.
  */
 #define IPATH_S_SIGNAL_REQ_WR	0x01
 #define IPATH_S_FENCE_PENDING	0x02
 #define IPATH_S_RDMAR_PENDING	0x04
 #define IPATH_S_ACK_PENDING	0x08
+#define IPATH_S_BUSY		0x10
+#define IPATH_S_WAITING		0x20
+#define IPATH_S_WAIT_SSN_CREDIT	0x40
+#define IPATH_S_WAIT_DMA	0x80
+
+#define IPATH_S_ANY_WAIT (IPATH_S_FENCE_PENDING | IPATH_S_RDMAR_PENDING | \
+	IPATH_S_WAITING | IPATH_S_WAIT_SSN_CREDIT | IPATH_S_WAIT_DMA)
 
 #define IPATH_PSN_CREDIT	512
 
@@ -573,13 +604,11 @@
 	u32 n_rnr_naks;
 	u32 n_other_naks;
 	u32 n_timeouts;
-	u32 n_rc_stalls;
 	u32 n_pkt_drops;
 	u32 n_vl15_dropped;
 	u32 n_wqe_errs;
 	u32 n_rdma_dup_busy;
 	u32 n_piowait;
-	u32 n_no_piobuf;
 	u32 n_unaligned;
 	u32 port_cap_flags;
 	u32 pma_sample_start;
@@ -657,6 +686,17 @@
 	return container_of(ibdev, struct ipath_ibdev, ibdev);
 }
 
+/*
+ * This must be called with s_lock held.
+ */
+static inline void ipath_schedule_send(struct ipath_qp *qp)
+{
+	if (qp->s_flags & IPATH_S_ANY_WAIT)
+		qp->s_flags &= ~IPATH_S_ANY_WAIT;
+	if (!(qp->s_flags & IPATH_S_BUSY))
+		tasklet_hi_schedule(&qp->s_task);
+}
+
 int ipath_process_mad(struct ib_device *ibdev,
 		      int mad_flags,
 		      u8 port_num,
@@ -706,12 +746,10 @@
 int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 		   int attr_mask, struct ib_qp_init_attr *init_attr);
 
-void ipath_free_all_qps(struct ipath_qp_table *qpt);
+unsigned ipath_free_all_qps(struct ipath_qp_table *qpt);
 
 int ipath_init_qp_table(struct ipath_ibdev *idev, int size);
 
-void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc);
-
 void ipath_get_credit(struct ipath_qp *qp, u32 aeth);
 
 unsigned ipath_ib_rate_to_mult(enum ib_rate rate);
@@ -729,7 +767,9 @@
 void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
 		  int has_grh, void *data, u32 tlen, struct ipath_qp *qp);
 
-void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc);
+void ipath_restart_rc(struct ipath_qp *qp, u32 psn);
+
+void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err);
 
 int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr);
 
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 2f199c5..4521319 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -246,7 +246,7 @@
 	if (context)
 		ib_umem_release(cq->umem);
 	else
-		mlx4_ib_free_cq_buf(dev, &cq->buf, entries);
+		mlx4_ib_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
 
 err_db:
 	if (!context)
@@ -434,7 +434,7 @@
 		mlx4_ib_db_unmap_user(to_mucontext(cq->uobject->context), &mcq->db);
 		ib_umem_release(mcq->umem);
 	} else {
-		mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe + 1);
+		mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe);
 		mlx4_db_free(dev->dev, &mcq->db);
 	}
 
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 9f7364a..a4e9269 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -91,10 +91,6 @@
 module_param_named(debug_level, nes_debug_level, uint, 0644);
 MODULE_PARM_DESC(debug_level, "Enable debug output level");
 
-unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
-module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR);
-MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation");
-
 LIST_HEAD(nes_adapter_list);
 static LIST_HEAD(nes_dev_list);
 
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 1f9f7bf..61b46e9 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -173,7 +173,6 @@
 extern unsigned int send_first;
 extern unsigned int nes_drv_opt;
 extern unsigned int nes_debug_level;
-extern unsigned int nes_lro_max_aggr;
 
 extern struct list_head nes_adapter_list;
 
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 8dc70f9..d3278f1 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -42,6 +42,10 @@
 
 #include "nes.h"
 
+static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
+module_param(nes_lro_max_aggr, uint, 0444);
+MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
+
 static u32 crit_err_count;
 u32 int_mod_timer_init;
 u32 int_mod_cq_depth_256;
@@ -1738,7 +1742,7 @@
 			jumbomode = 1;
 		nes_nic_init_timer_defaults(nesdev, jumbomode);
 	}
-	nesvnic->lro_mgr.max_aggr       = NES_LRO_MAX_AGGR;
+	nesvnic->lro_mgr.max_aggr       = nes_lro_max_aggr;
 	nesvnic->lro_mgr.max_desc       = NES_MAX_LRO_DESCRIPTORS;
 	nesvnic->lro_mgr.lro_arr        = nesvnic->lro_desc;
 	nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 9044f88..ca126fc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -334,6 +334,7 @@
 #endif
 	int	hca_caps;
 	struct ipoib_ethtool_st ethtool;
+	struct timer_list poll_timer;
 };
 
 struct ipoib_ah {
@@ -404,6 +405,7 @@
 
 int ipoib_poll(struct napi_struct *napi, int budget);
 void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr);
+void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr);
 
 struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
 				 struct ib_pd *pd, struct ib_ah_attr *attr);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 97b815c..f429bce 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -461,6 +461,26 @@
 	netif_rx_schedule(dev, &priv->napi);
 }
 
+static void drain_tx_cq(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tx_lock, flags);
+	while (poll_tx(priv))
+		; /* nothing */
+
+	if (netif_queue_stopped(dev))
+		mod_timer(&priv->poll_timer, jiffies + 1);
+
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
+}
+
+void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr)
+{
+	drain_tx_cq((struct net_device *)dev_ptr);
+}
+
 static inline int post_send(struct ipoib_dev_priv *priv,
 			    unsigned int wr_id,
 			    struct ib_ah *address, u32 qpn,
@@ -555,12 +575,22 @@
 	else
 		priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
 
+	if (++priv->tx_outstanding == ipoib_sendq_size) {
+		ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
+		if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
+			ipoib_warn(priv, "request notify on send CQ failed\n");
+		netif_stop_queue(dev);
+	}
+
 	if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
 			       address->ah, qpn, tx_req, phead, hlen))) {
 		ipoib_warn(priv, "post_send failed\n");
 		++dev->stats.tx_errors;
+		--priv->tx_outstanding;
 		ipoib_dma_unmap_tx(priv->ca, tx_req);
 		dev_kfree_skb_any(skb);
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
 	} else {
 		dev->trans_start = jiffies;
 
@@ -568,14 +598,11 @@
 		++priv->tx_head;
 		skb_orphan(skb);
 
-		if (++priv->tx_outstanding == ipoib_sendq_size) {
-			ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
-			netif_stop_queue(dev);
-		}
 	}
 
 	if (unlikely(priv->tx_outstanding > MAX_SEND_CQE))
-		poll_tx(priv);
+		while (poll_tx(priv))
+			; /* nothing */
 }
 
 static void __ipoib_reap_ah(struct net_device *dev)
@@ -609,6 +636,11 @@
 				   round_jiffies_relative(HZ));
 }
 
+static void ipoib_ib_tx_timer_func(unsigned long ctx)
+{
+	drain_tx_cq((struct net_device *)ctx);
+}
+
 int ipoib_ib_dev_open(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -645,6 +677,10 @@
 	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
 			   round_jiffies_relative(HZ));
 
+	init_timer(&priv->poll_timer);
+	priv->poll_timer.function = ipoib_ib_tx_timer_func;
+	priv->poll_timer.data = (unsigned long)dev;
+
 	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
 
 	return 0;
@@ -810,6 +846,7 @@
 	ipoib_dbg(priv, "All sends and receives done.\n");
 
 timeout:
+	del_timer_sync(&priv->poll_timer);
 	qp_attr.qp_state = IB_QPS_RESET;
 	if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
 		ipoib_warn(priv, "Failed to modify QP to RESET state\n");
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index c1e7ece..8766d29 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -187,7 +187,8 @@
 		goto out_free_mr;
 	}
 
-	priv->send_cq = ib_create_cq(priv->ca, NULL, NULL, dev, ipoib_sendq_size, 0);
+	priv->send_cq = ib_create_cq(priv->ca, ipoib_send_comp_handler, NULL,
+				     dev, ipoib_sendq_size, 0);
 	if (IS_ERR(priv->send_cq)) {
 		printk(KERN_WARNING "%s: failed to create send CQ\n", ca->name);
 		goto out_free_recv_cq;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 92b6834..3ad8bd9 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -14,7 +14,7 @@
 
 config INPUT_PCSPKR
 	tristate "PC Speaker support"
-	depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+	depends on PCSPKR_PLATFORM
 	depends on SND_PCSP=n
 	help
 	  Say Y here if you want the standard PC Speaker to be used for
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 02b3ad8..edfedd9 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -69,6 +69,7 @@
 #include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/hil.h>
+#include <linux/semaphore.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index 3b4e13b..f451c73 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -25,7 +25,7 @@
 #elif defined(__arm__)
 /* defined in include/asm-arm/arch-xxx/irqs.h */
 #include <asm/irq.h>
-#elif defined(CONFIG_SUPERH64)
+#elif defined(CONFIG_SH_CAYMAN)
 #include <asm/irq.h>
 #else
 # define I8042_KBD_IRQ	1
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index ebef4ce..29419a8 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -948,17 +948,17 @@
 {
 	g_cmsg= kmalloc(sizeof(_cmsg), GFP_KERNEL);
 	if (!g_cmsg)
-		return ENOMEM;
+		return -ENOMEM;
 	g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL);
 	if (!g_debbuf) {
 		kfree(g_cmsg);
-		return ENOMEM;
+		return -ENOMEM;
 	}
 	g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL);
 	if (!g_debbuf->buf) {
 		kfree(g_cmsg);
 		kfree(g_debbuf);
-		return ENOMEM;;
+		return -ENOMEM;;
 	}
 	g_debbuf->size = CDEBUG_GSIZE;
 	g_debbuf->buf[0] = 0;
diff --git a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig
index c6d8a70..c9e4231 100644
--- a/drivers/isdn/hysdn/Kconfig
+++ b/drivers/isdn/hysdn/Kconfig
@@ -3,7 +3,7 @@
 #
 config HYSDN
 	tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)"
-	depends on m && PROC_FS && PCI && BROKEN_ON_SMP
+	depends on m && PROC_FS && PCI
 	help
 	  Say Y here if you have one of Hypercope's active PCI ISDN cards
 	  Champ, Ergo and Metro. You will then get a module called hysdn.
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c
index 6cdbad3..3eb096f 100644
--- a/drivers/isdn/hysdn/boardergo.c
+++ b/drivers/isdn/hysdn/boardergo.c
@@ -64,10 +64,11 @@
 }				/* ergo_interrupt */
 
 /******************************************************************************/
-/* ergo_irq_bh is the function called by the immediate kernel task list after */
-/* being activated with queue_task and no interrupts active. This task is the */
-/* only one handling data transfer from or to the card after booting. The task */
-/* may be queued from everywhere (interrupts included).                       */
+/* ergo_irq_bh will be called as part of the kernel clearing its shared work  */
+/* queue sometime after a call to schedule_work has been made passing our     */
+/* work_struct. This task is the only one handling data transfer from or to   */
+/* the card after booting. The task may be queued from everywhere             */
+/* (interrupts included).                                                     */
 /******************************************************************************/
 static void
 ergo_irq_bh(struct work_struct *ugli_api)
@@ -90,7 +91,6 @@
 	card->hw_lock = 1;	/* we now lock the hardware */
 
 	do {
-		sti();		/* reenable other ints */
 		again = 0;	/* assume loop not to be repeated */
 
 		if (!dpr->ToHyFlag) {
@@ -110,7 +110,6 @@
 				again = 1;	/* restart loop */
 			}
 		}		/* a message has arrived for us */
-		cli();		/* no further ints */
 		if (again) {
 			dpr->ToHyInt = 1;
 			dpr->ToPcInt = 1;	/* interrupt to E1 for all cards */
@@ -242,7 +241,6 @@
 		byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RUN);	/* start E1 processor */
 		/* the interrupts are still masked */
 
-		sti();
 		msleep_interruptible(20);		/* Timeout 20ms */
 
 		if (((tDpramBootSpooler *) card->dpram)->Len != DPRAM_SPOOLER_DATA_SIZE) {
@@ -276,7 +274,6 @@
 	dst = sp->Data;		/* point to data in spool structure */
 	buflen = sp->Len;	/* maximum len of spooled data */
 	wr_mirror = sp->WrPtr;	/* only once read */
-	sti();
 
 	/* try until all bytes written or error */
 	i = 0x1000;		/* timeout value */
@@ -380,7 +377,6 @@
 #endif /* CONFIG_HYSDN_CAPI */
 			return (0);	/* success */
 		}		/* data has arrived */
-		sti();
 		msleep_interruptible(50);		/* Timeout 50ms */
 	}			/* wait until timeout */
 
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 2097820..b8b9e44 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -37,7 +37,7 @@
 #include <linux/device.h>
 #include <linux/kthread.h>
 #include <linux/platform_device.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
 #ifdef CONFIG_PPC
@@ -102,7 +102,7 @@
 } adb_handler[16];
 
 /*
- * The adb_handler_sem mutex protects all accesses to the original_address
+ * The adb_handler_mutex mutex protects all accesses to the original_address
  * and handler_id fields of adb_handler[i] for all i, and changes to the
  * handler field.
  * Accesses to the handler field are protected by the adb_handler_lock
@@ -110,7 +110,7 @@
  * time adb_unregister returns, we know that the old handler isn't being
  * called.
  */
-static DECLARE_MUTEX(adb_handler_sem);
+static DEFINE_MUTEX(adb_handler_mutex);
 static DEFINE_RWLOCK(adb_handler_lock);
 
 #if 0
@@ -355,7 +355,7 @@
 		msleep(500);
 	}
 
-	down(&adb_handler_sem);
+	mutex_lock(&adb_handler_mutex);
 	write_lock_irq(&adb_handler_lock);
 	memset(adb_handler, 0, sizeof(adb_handler));
 	write_unlock_irq(&adb_handler_lock);
@@ -376,7 +376,7 @@
 		if (adb_controller->autopoll)
 			adb_controller->autopoll(autopoll_devs);
 	}
-	up(&adb_handler_sem);
+	mutex_unlock(&adb_handler_mutex);
 
 	blocking_notifier_call_chain(&adb_client_list,
 		ADB_MSG_POST_RESET, NULL);
@@ -454,7 +454,7 @@
 {
 	int i;
 
-	down(&adb_handler_sem);
+	mutex_lock(&adb_handler_mutex);
 	ids->nids = 0;
 	for (i = 1; i < 16; i++) {
 		if ((adb_handler[i].original_address == default_id) &&
@@ -472,7 +472,7 @@
 			ids->id[ids->nids++] = i;
 		}
 	}
-	up(&adb_handler_sem);
+	mutex_unlock(&adb_handler_mutex);
 	return ids->nids;
 }
 
@@ -481,7 +481,7 @@
 {
 	int ret = -ENODEV;
 
-	down(&adb_handler_sem);
+	mutex_lock(&adb_handler_mutex);
 	write_lock_irq(&adb_handler_lock);
 	if (adb_handler[index].handler) {
 		while(adb_handler[index].busy) {
@@ -493,7 +493,7 @@
 		adb_handler[index].handler = NULL;
 	}
 	write_unlock_irq(&adb_handler_lock);
-	up(&adb_handler_sem);
+	mutex_unlock(&adb_handler_mutex);
 	return ret;
 }
 
@@ -557,19 +557,19 @@
 {
 	int ret;
 
-	down(&adb_handler_sem);
+	mutex_lock(&adb_handler_mutex);
 	ret = try_handler_change(address, new_id);
-	up(&adb_handler_sem);
+	mutex_unlock(&adb_handler_mutex);
 	return ret;
 }
 
 int
 adb_get_infos(int address, int *original_address, int *handler_id)
 {
-	down(&adb_handler_sem);
+	mutex_lock(&adb_handler_mutex);
 	*original_address = adb_handler[address].original_address;
 	*handler_id = adb_handler[address].handler_id;
-	up(&adb_handler_sem);
+	mutex_unlock(&adb_handler_mutex);
 
 	return (*original_address != 0);
 }
@@ -628,10 +628,10 @@
 	case ADB_QUERY_GETDEVINFO:
 		if (req->nbytes < 3)
 			break;
-		down(&adb_handler_sem);
+		mutex_lock(&adb_handler_mutex);
 		req->reply[0] = adb_handler[req->data[2]].original_address;
 		req->reply[1] = adb_handler[req->data[2]].handler_id;
-		up(&adb_handler_sem);
+		mutex_unlock(&adb_handler_mutex);
 		req->complete = 1;
 		req->reply_len = 2;
 		adb_write_done(req);
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 1e0a69a..ddfb426 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -122,6 +122,7 @@
 #include <linux/kmod.h>
 #include <linux/i2c.h>
 #include <linux/kthread.h>
+#include <linux/mutex.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
@@ -169,7 +170,7 @@
 static s32				dimm_output_clamp;
 static int 				fcu_rpm_shift;
 static int				fcu_tickle_ticks;
-static DECLARE_MUTEX(driver_lock);
+static DEFINE_MUTEX(driver_lock);
 
 /*
  * We have 3 types of CPU PID control. One is "split" old style control
@@ -729,9 +730,9 @@
 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf)	\
 {								\
 	ssize_t r;						\
-	down(&driver_lock);					\
+	mutex_lock(&driver_lock);					\
 	r = sprintf(buf, "%d.%03d", FIX32TOPRINT(data));	\
-	up(&driver_lock);					\
+	mutex_unlock(&driver_lock);					\
 	return r;						\
 }
 #define BUILD_SHOW_FUNC_INT(name, data)				\
@@ -1803,11 +1804,11 @@
 {
 	DBG("main_control_loop started\n");
 
-	down(&driver_lock);
+	mutex_lock(&driver_lock);
 
 	if (start_fcu() < 0) {
 		printk(KERN_ERR "kfand: failed to start FCU\n");
-		up(&driver_lock);
+		mutex_unlock(&driver_lock);
 		goto out;
 	}
 
@@ -1822,14 +1823,14 @@
 
 	fcu_tickle_ticks = FCU_TICKLE_TICKS;
 
-	up(&driver_lock);
+	mutex_unlock(&driver_lock);
 
 	while (state == state_attached) {
 		unsigned long elapsed, start;
 
 		start = jiffies;
 
-		down(&driver_lock);
+		mutex_lock(&driver_lock);
 
 		/* Tickle the FCU just in case */
 		if (--fcu_tickle_ticks < 0) {
@@ -1861,7 +1862,7 @@
 			do_monitor_slots(&slots_state);
 		else
 			do_monitor_drives(&drives_state);
-		up(&driver_lock);
+		mutex_unlock(&driver_lock);
 
 		if (critical_state == 1) {
 			printk(KERN_WARNING "Temperature control detected a critical condition\n");
@@ -2019,13 +2020,13 @@
  */
 static int therm_pm72_attach(struct i2c_adapter *adapter)
 {
-	down(&driver_lock);
+	mutex_lock(&driver_lock);
 
 	/* Check state */
 	if (state == state_detached)
 		state = state_attaching;
 	if (state != state_attaching) {
-		up(&driver_lock);
+		mutex_unlock(&driver_lock);
 		return 0;
 	}
 
@@ -2054,7 +2055,7 @@
 		state = state_attached;
 		start_control_loops();
 	}
-	up(&driver_lock);
+	mutex_unlock(&driver_lock);
 
 	return 0;
 }
@@ -2065,16 +2066,16 @@
  */
 static int therm_pm72_detach(struct i2c_adapter *adapter)
 {
-	down(&driver_lock);
+	mutex_lock(&driver_lock);
 
 	if (state != state_detached)
 		state = state_detaching;
 
 	/* Stop control loops if any */
 	DBG("stopping control loops\n");
-	up(&driver_lock);
+	mutex_unlock(&driver_lock);
 	stop_control_loops();
-	down(&driver_lock);
+	mutex_lock(&driver_lock);
 
 	if (u3_0 != NULL && !strcmp(adapter->name, "u3 0")) {
 		DBG("lost U3-0, disposing control loops\n");
@@ -2090,7 +2091,7 @@
 	if (u3_0 == NULL && u3_1 == NULL)
 		state = state_detached;
 
-	up(&driver_lock);
+	mutex_unlock(&driver_lock);
 
 	return 0;
 }
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 797918d..7f2be4b 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/i2c.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 #include <asm/prom.h>
 #include <asm/smu.h>
 #include <asm/pmac_low_i2c.h>
@@ -36,7 +36,7 @@
 struct wf_sat {
 	int			nr;
 	atomic_t		refcnt;
-	struct semaphore	mutex;
+	struct mutex		mutex;
 	unsigned long		last_read; /* jiffies when cache last updated */
 	u8			cache[16];
 	struct i2c_client	i2c;
@@ -163,7 +163,7 @@
 	if (sat->i2c.adapter == NULL)
 		return -ENODEV;
 
-	down(&sat->mutex);
+	mutex_lock(&sat->mutex);
 	if (time_after(jiffies, (sat->last_read + MAX_AGE))) {
 		err = wf_sat_read_cache(sat);
 		if (err)
@@ -182,7 +182,7 @@
 	err = 0;
 
  fail:
-	up(&sat->mutex);
+	mutex_unlock(&sat->mutex);
 	return err;
 }
 
@@ -233,7 +233,7 @@
 	sat->nr = -1;
 	sat->node = of_node_get(dev);
 	atomic_set(&sat->refcnt, 0);
-	init_MUTEX(&sat->mutex);
+	mutex_init(&sat->mutex);
 	sat->i2c.addr = (addr >> 1) & 0x7f;
 	sat->i2c.adapter = adapter;
 	sat->i2c.driver = &wf_sat_driver;
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 0b85117..1074824 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -250,6 +250,7 @@
 {
 	linear_conf_t *conf;
 
+	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
 	conf = linear_conf(mddev, mddev->raid_disks);
 
 	if (!conf)
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 42ee1a2..4f4d1f3 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -417,6 +417,7 @@
 	 * bookkeeping area. [whatever we allocate in multipath_run(),
 	 * should be freed in multipath_stop()]
 	 */
+	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
 
 	conf = kzalloc(sizeof(multipath_conf_t), GFP_KERNEL);
 	mddev->private = conf;
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 818b482..914c04d 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -280,6 +280,7 @@
 	       (mddev->chunk_size>>1)-1);
 	blk_queue_max_sectors(mddev->queue, mddev->chunk_size >> 9);
 	blk_queue_segment_boundary(mddev->queue, (mddev->chunk_size>>1) - 1);
+	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
 
 	conf = kmalloc(sizeof (raid0_conf_t), GFP_KERNEL);
 	if (!conf)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6778b7c..ac409b7 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1935,6 +1935,9 @@
 	if (!conf->r1bio_pool)
 		goto out_no_mem;
 
+	spin_lock_init(&conf->device_lock);
+	mddev->queue->queue_lock = &conf->device_lock;
+
 	rdev_for_each(rdev, tmp, mddev) {
 		disk_idx = rdev->raid_disk;
 		if (disk_idx >= mddev->raid_disks
@@ -1958,7 +1961,6 @@
 	}
 	conf->raid_disks = mddev->raid_disks;
 	conf->mddev = mddev;
-	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
 
 	spin_lock_init(&conf->resync_lock);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 5938fa9..8536ede 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -886,7 +886,7 @@
 	 */
 	raid10_find_phys(conf, r10_bio);
  retry_write:
-	blocked_rdev = 0;
+	blocked_rdev = NULL;
 	rcu_read_lock();
 	for (i = 0;  i < conf->copies; i++) {
 		int d = r10_bio->devs[i].devnum;
@@ -2082,6 +2082,9 @@
 		goto out_free_conf;
 	}
 
+	spin_lock_init(&conf->device_lock);
+	mddev->queue->queue_lock = &conf->device_lock;
+
 	rdev_for_each(rdev, tmp, mddev) {
 		disk_idx = rdev->raid_disk;
 		if (disk_idx >= mddev->raid_disks
@@ -2103,7 +2106,6 @@
 
 		disk->head_position = 0;
 	}
-	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
 
 	spin_lock_init(&conf->resync_lock);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 087eee0..93fde48 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2369,8 +2369,8 @@
 
 	/* complete a check operation */
 	if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
-	    clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
-	    clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
+		clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
+		clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
 		if (s->failed == 0) {
 			if (sh->ops.zero_sum_result == 0)
 				/* parity is correct (on disc,
@@ -2400,16 +2400,6 @@
 			canceled_check = 1; /* STRIPE_INSYNC is not set */
 	}
 
-	/* check if we can clear a parity disk reconstruct */
-	if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
-		test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
-
-		clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
-	}
-
 	/* start a new check operation if there are no failures, the stripe is
 	 * not insync, and a repair is not in flight
 	 */
@@ -2424,6 +2414,17 @@
 		}
 	}
 
+	/* check if we can clear a parity disk reconstruct */
+	if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
+	    test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
+
+		clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
+		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
+		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
+		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
+	}
+
+
 	/* Wait for check parity and compute block operations to complete
 	 * before write-back.  If a failure occurred while the check operation
 	 * was in flight we need to cycle this stripe through handle_stripe
@@ -4256,6 +4257,7 @@
 			goto abort;
 	}
 	spin_lock_init(&conf->device_lock);
+	mddev->queue->queue_lock = &conf->device_lock;
 	init_waitqueue_head(&conf->wait_for_stripe);
 	init_waitqueue_head(&conf->wait_for_overlap);
 	INIT_LIST_HEAD(&conf->handle_list);
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index ddf57e1..7a7803b 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -89,8 +89,7 @@
 
 config VIDEO_MEDIA
 	tristate
-	default DVB_CORE || VIDEO_DEV
-	depends on DVB_CORE || VIDEO_DEV
+	default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV)
 
 comment "Multimedia drivers"
 
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 73f742c..cc11c4c 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,6 +2,8 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
+obj-y := common/
+
 obj-$(CONFIG_VIDEO_MEDIA) += common/
 
 # Since hybrid devices are here, should be compiled if DVB and/or V4L
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 5be85ff..d620654 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -1,6 +1,6 @@
 config MEDIA_ATTACH
 	bool "Load and attach frontend and tuner driver modules as needed"
-	depends on DVB_CORE
+	depends on VIDEO_MEDIA
 	depends on MODULES
 	help
 	  Remove the static dependency of DVB card drivers on all
@@ -19,10 +19,10 @@
 
 config MEDIA_TUNER
 	tristate
-	default DVB_CORE || VIDEO_DEV
-	depends on DVB_CORE || VIDEO_DEV
-	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
+	default VIDEO_MEDIA && I2C
+	depends on VIDEO_MEDIA && I2C
+	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
@@ -46,7 +46,7 @@
 
 config MEDIA_TUNER_SIMPLE
 	tristate "Simple tuner support"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_TDA9887
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
@@ -54,7 +54,7 @@
 
 config MEDIA_TUNER_TDA8290
 	tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_TDA827X
 	select MEDIA_TUNER_TDA18271
 	default m if MEDIA_TUNER_CUSTOMIZE
@@ -63,21 +63,21 @@
 
 config MEDIA_TUNER_TDA827X
 	tristate "Philips TDA827X silicon tuner"
-	depends on DVB_CORE && I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A DVB-T silicon tuner module. Say Y when you want to support this tuner.
 
 config MEDIA_TUNER_TDA18271
 	tristate "NXP TDA18271 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A silicon tuner module. Say Y when you want to support this tuner.
 
 config MEDIA_TUNER_TDA9887
 	tristate "TDA 9885/6/7 analog IF demodulator"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	  Say Y here to include support for Philips TDA9885/6/7
@@ -85,67 +85,79 @@
 
 config MEDIA_TUNER_TEA5761
 	tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
-	depends on I2C && EXPERIMENTAL
+	depends on VIDEO_MEDIA && I2C
+	depends on EXPERIMENTAL
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	  Say Y here to include support for the Philips TEA5761 radio tuner.
 
 config MEDIA_TUNER_TEA5767
 	tristate "TEA 5767 radio tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	  Say Y here to include support for the Philips TEA5767 radio tuner.
 
 config MEDIA_TUNER_MT20XX
 	tristate "Microtune 2032 / 2050 tuners"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	  Say Y here to include support for the MT2032 / MT2050 tuner.
 
 config MEDIA_TUNER_MT2060
 	tristate "Microtune MT2060 silicon IF tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon IF tuner MT2060 from Microtune.
 
 config MEDIA_TUNER_MT2266
 	tristate "Microtune MT2266 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon baseband tuner MT2266 from Microtune.
 
 config MEDIA_TUNER_MT2131
 	tristate "Microtune MT2131 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon baseband tuner MT2131 from Microtune.
 
 config MEDIA_TUNER_QT1010
 	tristate "Quantek QT1010 silicon tuner"
-	depends on DVB_CORE && I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon tuner QT1010 from Quantek.
 
 config MEDIA_TUNER_XC2028
 	tristate "XCeive xc2028/xc3028 tuners"
-	depends on I2C && FW_LOADER
+	depends on VIDEO_MEDIA && I2C
+	depends on HOTPLUG
+	select FW_LOADER
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	  Say Y here to include support for the xc2028/xc3028 tuners.
 
 config MEDIA_TUNER_XC5000
 	tristate "Xceive XC5000 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
+	depends on HOTPLUG
+	select FW_LOADER
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon tuner XC5000 from Xceive.
 	  This device is only used inside a SiP called togther with a
 	  demodulator for now.
 
+config MEDIA_TUNER_MXL5005S
+	tristate "MaxLinear MSL5005S silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A driver for the silicon tuner MXL5005S from MaxLinear.
+
 endif # MEDIA_TUNER_CUSTOMIZE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 236d9932..55f7e67 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -20,6 +20,7 @@
 obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
+obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
new file mode 100644
index 0000000..5d05b53
--- /dev/null
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -0,0 +1,4110 @@
+/*
+    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+    Copyright (C) 2008 MaxLinear
+    Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+      Functions:
+	mxl5005s_reset()
+	mxl5005s_writereg()
+	mxl5005s_writeregs()
+	mxl5005s_init()
+	mxl5005s_reconfigure()
+	mxl5005s_AssignTunerMode()
+	mxl5005s_set_params()
+	mxl5005s_get_frequency()
+	mxl5005s_get_bandwidth()
+	mxl5005s_release()
+	mxl5005s_attach()
+
+    Copyright (C) 2008 Realtek
+    Copyright (C) 2008 Jan Hoogenraad
+      Functions:
+	mxl5005s_SetRfFreqHz()
+
+    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.
+
+    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.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+    History of this driver (Steven Toth):
+      I was given a public release of a linux driver that included
+      support for the MaxLinear MXL5005S silicon tuner. Analysis of
+      the tuner driver showed clearly three things.
+
+      1. The tuner driver didn't support the LinuxTV tuner API
+	 so the code Realtek added had to be removed.
+
+      2. A significant amount of the driver is reference driver code
+	 from MaxLinear, I felt it was important to identify and
+	 preserve this.
+
+      3. New code has to be added to interface correctly with the
+	 LinuxTV API, as a regular kernel module.
+
+      Other than the reference driver enum's, I've clearly marked
+      sections of the code and retained the copyright of the
+      respective owners.
+*/
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "mxl5005s.h"
+
+static int debug;
+
+#define dprintk(level, arg...) do {    \
+	if (level <= debug)            \
+		printk(arg);    \
+	} while (0)
+
+#define TUNER_REGS_NUM          104
+#define INITCTRL_NUM            40
+
+#ifdef _MXL_PRODUCTION
+#define CHCTRL_NUM              39
+#else
+#define CHCTRL_NUM              36
+#endif
+
+#define MXLCTRL_NUM             189
+#define MASTER_CONTROL_ADDR     9
+
+/* Enumeration of Master Control Register State */
+enum master_control_state {
+	MC_LOAD_START = 1,
+	MC_POWER_DOWN,
+	MC_SYNTH_RESET,
+	MC_SEQ_OFF
+};
+
+/* Enumeration of MXL5005 Tuner Modulation Type */
+enum {
+	MXL_DEFAULT_MODULATION = 0,
+	MXL_DVBT,
+	MXL_ATSC,
+	MXL_QAM,
+	MXL_ANALOG_CABLE,
+	MXL_ANALOG_OTA
+} tuner_modu_type;
+
+/* MXL5005 Tuner Register Struct */
+struct TunerReg {
+	u16 Reg_Num;	/* Tuner Register Address */
+	u16 Reg_Val;	/* Current sw programmed value waiting to be writen */
+};
+
+enum {
+	/* Initialization Control Names */
+	DN_IQTN_AMP_CUT = 1,       /* 1 */
+	BB_MODE,                   /* 2 */
+	BB_BUF,                    /* 3 */
+	BB_BUF_OA,                 /* 4 */
+	BB_ALPF_BANDSELECT,        /* 5 */
+	BB_IQSWAP,                 /* 6 */
+	BB_DLPF_BANDSEL,           /* 7 */
+	RFSYN_CHP_GAIN,            /* 8 */
+	RFSYN_EN_CHP_HIGAIN,       /* 9 */
+	AGC_IF,                    /* 10 */
+	AGC_RF,                    /* 11 */
+	IF_DIVVAL,                 /* 12 */
+	IF_VCO_BIAS,               /* 13 */
+	CHCAL_INT_MOD_IF,          /* 14 */
+	CHCAL_FRAC_MOD_IF,         /* 15 */
+	DRV_RES_SEL,               /* 16 */
+	I_DRIVER,                  /* 17 */
+	EN_AAF,                    /* 18 */
+	EN_3P,                     /* 19 */
+	EN_AUX_3P,                 /* 20 */
+	SEL_AAF_BAND,              /* 21 */
+	SEQ_ENCLK16_CLK_OUT,       /* 22 */
+	SEQ_SEL4_16B,              /* 23 */
+	XTAL_CAPSELECT,            /* 24 */
+	IF_SEL_DBL,                /* 25 */
+	RFSYN_R_DIV,               /* 26 */
+	SEQ_EXTSYNTHCALIF,         /* 27 */
+	SEQ_EXTDCCAL,              /* 28 */
+	AGC_EN_RSSI,               /* 29 */
+	RFA_ENCLKRFAGC,            /* 30 */
+	RFA_RSSI_REFH,             /* 31 */
+	RFA_RSSI_REF,              /* 32 */
+	RFA_RSSI_REFL,             /* 33 */
+	RFA_FLR,                   /* 34 */
+	RFA_CEIL,                  /* 35 */
+	SEQ_EXTIQFSMPULSE,         /* 36 */
+	OVERRIDE_1,                /* 37 */
+	BB_INITSTATE_DLPF_TUNE,    /* 38 */
+	TG_R_DIV,                  /* 39 */
+	EN_CHP_LIN_B,              /* 40 */
+
+	/* Channel Change Control Names */
+	DN_POLY = 51,              /* 51 */
+	DN_RFGAIN,                 /* 52 */
+	DN_CAP_RFLPF,              /* 53 */
+	DN_EN_VHFUHFBAR,           /* 54 */
+	DN_GAIN_ADJUST,            /* 55 */
+	DN_IQTNBUF_AMP,            /* 56 */
+	DN_IQTNGNBFBIAS_BST,       /* 57 */
+	RFSYN_EN_OUTMUX,           /* 58 */
+	RFSYN_SEL_VCO_OUT,         /* 59 */
+	RFSYN_SEL_VCO_HI,          /* 60 */
+	RFSYN_SEL_DIVM,            /* 61 */
+	RFSYN_RF_DIV_BIAS,         /* 62 */
+	DN_SEL_FREQ,               /* 63 */
+	RFSYN_VCO_BIAS,            /* 64 */
+	CHCAL_INT_MOD_RF,          /* 65 */
+	CHCAL_FRAC_MOD_RF,         /* 66 */
+	RFSYN_LPF_R,               /* 67 */
+	CHCAL_EN_INT_RF,           /* 68 */
+	TG_LO_DIVVAL,              /* 69 */
+	TG_LO_SELVAL,              /* 70 */
+	TG_DIV_VAL,                /* 71 */
+	TG_VCO_BIAS,               /* 72 */
+	SEQ_EXTPOWERUP,            /* 73 */
+	OVERRIDE_2,                /* 74 */
+	OVERRIDE_3,                /* 75 */
+	OVERRIDE_4,                /* 76 */
+	SEQ_FSM_PULSE,             /* 77 */
+	GPIO_4B,                   /* 78 */
+	GPIO_3B,                   /* 79 */
+	GPIO_4,                    /* 80 */
+	GPIO_3,                    /* 81 */
+	GPIO_1B,                   /* 82 */
+	DAC_A_ENABLE,              /* 83 */
+	DAC_B_ENABLE,              /* 84 */
+	DAC_DIN_A,                 /* 85 */
+	DAC_DIN_B,                 /* 86 */
+#ifdef _MXL_PRODUCTION
+	RFSYN_EN_DIV,              /* 87 */
+	RFSYN_DIVM,                /* 88 */
+	DN_BYPASS_AGC_I2C          /* 89 */
+#endif
+} MXL5005_ControlName;
+
+/*
+ * The following context is source code provided by MaxLinear.
+ * MaxLinear source code - Common_MXL.h (?)
+ */
+
+/* Constants */
+#define MXL5005S_REG_WRITING_TABLE_LEN_MAX	104
+#define MXL5005S_LATCH_BYTE			0xfe
+
+/* Register address, MSB, and LSB */
+#define MXL5005S_BB_IQSWAP_ADDR			59
+#define MXL5005S_BB_IQSWAP_MSB			0
+#define MXL5005S_BB_IQSWAP_LSB			0
+
+#define MXL5005S_BB_DLPF_BANDSEL_ADDR		53
+#define MXL5005S_BB_DLPF_BANDSEL_MSB		4
+#define MXL5005S_BB_DLPF_BANDSEL_LSB		3
+
+/* Standard modes */
+enum {
+	MXL5005S_STANDARD_DVBT,
+	MXL5005S_STANDARD_ATSC,
+};
+#define MXL5005S_STANDARD_MODE_NUM		2
+
+/* Bandwidth modes */
+enum {
+	MXL5005S_BANDWIDTH_6MHZ = 6000000,
+	MXL5005S_BANDWIDTH_7MHZ = 7000000,
+	MXL5005S_BANDWIDTH_8MHZ = 8000000,
+};
+#define MXL5005S_BANDWIDTH_MODE_NUM		3
+
+/* MXL5005 Tuner Control Struct */
+struct TunerControl {
+	u16 Ctrl_Num;	/* Control Number */
+	u16 size;	/* Number of bits to represent Value */
+	u16 addr[25];	/* Array of Tuner Register Address for each bit pos */
+	u16 bit[25];	/* Array of bit pos in Reg Addr for each bit pos */
+	u16 val[25];	/* Binary representation of Value */
+};
+
+/* MXL5005 Tuner Struct */
+struct mxl5005s_state {
+	u8	Mode;		/* 0: Analog Mode ; 1: Digital Mode */
+	u8	IF_Mode;	/* for Analog Mode, 0: zero IF; 1: low IF */
+	u32	Chan_Bandwidth;	/* filter  channel bandwidth (6, 7, 8) */
+	u32	IF_OUT;		/* Desired IF Out Frequency */
+	u16	IF_OUT_LOAD;	/* IF Out Load Resistor (200/300 Ohms) */
+	u32	RF_IN;		/* RF Input Frequency */
+	u32	Fxtal;		/* XTAL Frequency */
+	u8	AGC_Mode;	/* AGC Mode 0: Dual AGC; 1: Single AGC */
+	u16	TOP;		/* Value: take over point */
+	u8	CLOCK_OUT;	/* 0: turn off clk out; 1: turn on clock out */
+	u8	DIV_OUT;	/* 4MHz or 16MHz */
+	u8	CAPSELECT;	/* 0: disable On-Chip pulling cap; 1: enable */
+	u8	EN_RSSI;	/* 0: disable RSSI; 1: enable RSSI */
+
+	/* Modulation Type; */
+	/* 0 - Default;	1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
+	u8	Mod_Type;
+
+	/* Tracking Filter Type */
+	/* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
+	u8	TF_Type;
+
+	/* Calculated Settings */
+	u32	RF_LO;		/* Synth RF LO Frequency */
+	u32	IF_LO;		/* Synth IF LO Frequency */
+	u32	TG_LO;		/* Synth TG_LO Frequency */
+
+	/* Pointers to ControlName Arrays */
+	u16	Init_Ctrl_Num;		/* Number of INIT Control Names */
+	struct TunerControl
+		Init_Ctrl[INITCTRL_NUM]; /* INIT Control Names Array Pointer */
+
+	u16	CH_Ctrl_Num;		/* Number of CH Control Names */
+	struct TunerControl
+		CH_Ctrl[CHCTRL_NUM];	/* CH Control Name Array Pointer */
+
+	u16	MXL_Ctrl_Num;		/* Number of MXL Control Names */
+	struct TunerControl
+		MXL_Ctrl[MXLCTRL_NUM];	/* MXL Control Name Array Pointer */
+
+	/* Pointer to Tuner Register Array */
+	u16	TunerRegs_Num;		/* Number of Tuner Registers */
+	struct TunerReg
+		TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */
+
+	/* Linux driver framework specific */
+	struct mxl5005s_config *config;
+	struct dvb_frontend *frontend;
+	struct i2c_adapter *i2c;
+
+	/* Cache values */
+	u32 current_mode;
+
+};
+
+static u16 MXL_GetMasterControl(u8 *MasterReg, int state);
+static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value);
+static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value);
+static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
+	u8 bitVal);
+static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count);
+static u32 MXL_Ceiling(u32 value, u32 resolution);
+static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal);
+static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
+	u32 value, u16 controlGroup);
+static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val);
+static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count);
+static u32 MXL_GetXtalInt(u32 Xtal_Freq);
+static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq);
+static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe);
+static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe);
+static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count);
+static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
+	u8 *datatable, u8 len);
+static u16 MXL_IFSynthInit(struct dvb_frontend *fe);
+static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth);
+static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth);
+
+/* ----------------------------------------------------------------
+ * Begin: Custom code salvaged from the Realtek driver.
+ * Copyright (C) 2008 Realtek
+ * Copyright (C) 2008 Jan Hoogenraad
+ * This code is placed under the terms of the GNU General Public License
+ *
+ * Released by Realtek under GPLv2.
+ * Thanks to Realtek for a lot of support we received !
+ *
+ *  Revision: 080314 - original version
+ */
+
+static int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	int TableLen;
+
+	u32 IfDivval = 0;
+	unsigned char MasterControlByte;
+
+	dprintk(1, "%s() freq=%ld\n", __func__, RfFreqHz);
+
+	/* Set MxL5005S tuner RF frequency according to example code. */
+
+	/* Tuner RF frequency setting stage 0 */
+	MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
+	AddrTable[0] = MASTER_CONTROL_ADDR;
+	ByteTable[0] |= state->config->AgcMasterByte;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
+
+	/* Tuner RF frequency setting stage 1 */
+	MXL_TuneRF(fe, RfFreqHz);
+
+	MXL_ControlRead(fe, IF_DIVVAL, &IfDivval);
+
+	MXL_ControlWrite(fe, SEQ_FSM_PULSE, 0);
+	MXL_ControlWrite(fe, SEQ_EXTPOWERUP, 1);
+	MXL_ControlWrite(fe, IF_DIVVAL, 8);
+	MXL_GetCHRegister(fe, AddrTable, ByteTable, &TableLen);
+
+	MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
+	AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
+	ByteTable[TableLen] = MasterControlByte |
+		state->config->AgcMasterByte;
+	TableLen += 1;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+	/* Wait 30 ms. */
+	msleep(150);
+
+	/* Tuner RF frequency setting stage 2 */
+	MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1);
+	MXL_ControlWrite(fe, IF_DIVVAL, IfDivval);
+	MXL_GetCHRegister_ZeroIF(fe, AddrTable, ByteTable, &TableLen);
+
+	MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
+	AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
+	ByteTable[TableLen] = MasterControlByte |
+		state->config->AgcMasterByte ;
+	TableLen += 1;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+	msleep(100);
+
+	return 0;
+}
+/* End: Custom code taken from the Realtek driver */
+
+/* ----------------------------------------------------------------
+ * Begin: Reference driver code found in the Realtek driver.
+ * Copyright (C) 2008 MaxLinear
+ */
+static u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	state->TunerRegs_Num = TUNER_REGS_NUM ;
+
+	state->TunerRegs[0].Reg_Num = 9 ;
+	state->TunerRegs[0].Reg_Val = 0x40 ;
+
+	state->TunerRegs[1].Reg_Num = 11 ;
+	state->TunerRegs[1].Reg_Val = 0x19 ;
+
+	state->TunerRegs[2].Reg_Num = 12 ;
+	state->TunerRegs[2].Reg_Val = 0x60 ;
+
+	state->TunerRegs[3].Reg_Num = 13 ;
+	state->TunerRegs[3].Reg_Val = 0x00 ;
+
+	state->TunerRegs[4].Reg_Num = 14 ;
+	state->TunerRegs[4].Reg_Val = 0x00 ;
+
+	state->TunerRegs[5].Reg_Num = 15 ;
+	state->TunerRegs[5].Reg_Val = 0xC0 ;
+
+	state->TunerRegs[6].Reg_Num = 16 ;
+	state->TunerRegs[6].Reg_Val = 0x00 ;
+
+	state->TunerRegs[7].Reg_Num = 17 ;
+	state->TunerRegs[7].Reg_Val = 0x00 ;
+
+	state->TunerRegs[8].Reg_Num = 18 ;
+	state->TunerRegs[8].Reg_Val = 0x00 ;
+
+	state->TunerRegs[9].Reg_Num = 19 ;
+	state->TunerRegs[9].Reg_Val = 0x34 ;
+
+	state->TunerRegs[10].Reg_Num = 21 ;
+	state->TunerRegs[10].Reg_Val = 0x00 ;
+
+	state->TunerRegs[11].Reg_Num = 22 ;
+	state->TunerRegs[11].Reg_Val = 0x6B ;
+
+	state->TunerRegs[12].Reg_Num = 23 ;
+	state->TunerRegs[12].Reg_Val = 0x35 ;
+
+	state->TunerRegs[13].Reg_Num = 24 ;
+	state->TunerRegs[13].Reg_Val = 0x70 ;
+
+	state->TunerRegs[14].Reg_Num = 25 ;
+	state->TunerRegs[14].Reg_Val = 0x3E ;
+
+	state->TunerRegs[15].Reg_Num = 26 ;
+	state->TunerRegs[15].Reg_Val = 0x82 ;
+
+	state->TunerRegs[16].Reg_Num = 31 ;
+	state->TunerRegs[16].Reg_Val = 0x00 ;
+
+	state->TunerRegs[17].Reg_Num = 32 ;
+	state->TunerRegs[17].Reg_Val = 0x40 ;
+
+	state->TunerRegs[18].Reg_Num = 33 ;
+	state->TunerRegs[18].Reg_Val = 0x53 ;
+
+	state->TunerRegs[19].Reg_Num = 34 ;
+	state->TunerRegs[19].Reg_Val = 0x81 ;
+
+	state->TunerRegs[20].Reg_Num = 35 ;
+	state->TunerRegs[20].Reg_Val = 0xC9 ;
+
+	state->TunerRegs[21].Reg_Num = 36 ;
+	state->TunerRegs[21].Reg_Val = 0x01 ;
+
+	state->TunerRegs[22].Reg_Num = 37 ;
+	state->TunerRegs[22].Reg_Val = 0x00 ;
+
+	state->TunerRegs[23].Reg_Num = 41 ;
+	state->TunerRegs[23].Reg_Val = 0x00 ;
+
+	state->TunerRegs[24].Reg_Num = 42 ;
+	state->TunerRegs[24].Reg_Val = 0xF8 ;
+
+	state->TunerRegs[25].Reg_Num = 43 ;
+	state->TunerRegs[25].Reg_Val = 0x43 ;
+
+	state->TunerRegs[26].Reg_Num = 44 ;
+	state->TunerRegs[26].Reg_Val = 0x20 ;
+
+	state->TunerRegs[27].Reg_Num = 45 ;
+	state->TunerRegs[27].Reg_Val = 0x80 ;
+
+	state->TunerRegs[28].Reg_Num = 46 ;
+	state->TunerRegs[28].Reg_Val = 0x88 ;
+
+	state->TunerRegs[29].Reg_Num = 47 ;
+	state->TunerRegs[29].Reg_Val = 0x86 ;
+
+	state->TunerRegs[30].Reg_Num = 48 ;
+	state->TunerRegs[30].Reg_Val = 0x00 ;
+
+	state->TunerRegs[31].Reg_Num = 49 ;
+	state->TunerRegs[31].Reg_Val = 0x00 ;
+
+	state->TunerRegs[32].Reg_Num = 53 ;
+	state->TunerRegs[32].Reg_Val = 0x94 ;
+
+	state->TunerRegs[33].Reg_Num = 54 ;
+	state->TunerRegs[33].Reg_Val = 0xFA ;
+
+	state->TunerRegs[34].Reg_Num = 55 ;
+	state->TunerRegs[34].Reg_Val = 0x92 ;
+
+	state->TunerRegs[35].Reg_Num = 56 ;
+	state->TunerRegs[35].Reg_Val = 0x80 ;
+
+	state->TunerRegs[36].Reg_Num = 57 ;
+	state->TunerRegs[36].Reg_Val = 0x41 ;
+
+	state->TunerRegs[37].Reg_Num = 58 ;
+	state->TunerRegs[37].Reg_Val = 0xDB ;
+
+	state->TunerRegs[38].Reg_Num = 59 ;
+	state->TunerRegs[38].Reg_Val = 0x00 ;
+
+	state->TunerRegs[39].Reg_Num = 60 ;
+	state->TunerRegs[39].Reg_Val = 0x00 ;
+
+	state->TunerRegs[40].Reg_Num = 61 ;
+	state->TunerRegs[40].Reg_Val = 0x00 ;
+
+	state->TunerRegs[41].Reg_Num = 62 ;
+	state->TunerRegs[41].Reg_Val = 0x00 ;
+
+	state->TunerRegs[42].Reg_Num = 65 ;
+	state->TunerRegs[42].Reg_Val = 0xF8 ;
+
+	state->TunerRegs[43].Reg_Num = 66 ;
+	state->TunerRegs[43].Reg_Val = 0xE4 ;
+
+	state->TunerRegs[44].Reg_Num = 67 ;
+	state->TunerRegs[44].Reg_Val = 0x90 ;
+
+	state->TunerRegs[45].Reg_Num = 68 ;
+	state->TunerRegs[45].Reg_Val = 0xC0 ;
+
+	state->TunerRegs[46].Reg_Num = 69 ;
+	state->TunerRegs[46].Reg_Val = 0x01 ;
+
+	state->TunerRegs[47].Reg_Num = 70 ;
+	state->TunerRegs[47].Reg_Val = 0x50 ;
+
+	state->TunerRegs[48].Reg_Num = 71 ;
+	state->TunerRegs[48].Reg_Val = 0x06 ;
+
+	state->TunerRegs[49].Reg_Num = 72 ;
+	state->TunerRegs[49].Reg_Val = 0x00 ;
+
+	state->TunerRegs[50].Reg_Num = 73 ;
+	state->TunerRegs[50].Reg_Val = 0x20 ;
+
+	state->TunerRegs[51].Reg_Num = 76 ;
+	state->TunerRegs[51].Reg_Val = 0xBB ;
+
+	state->TunerRegs[52].Reg_Num = 77 ;
+	state->TunerRegs[52].Reg_Val = 0x13 ;
+
+	state->TunerRegs[53].Reg_Num = 81 ;
+	state->TunerRegs[53].Reg_Val = 0x04 ;
+
+	state->TunerRegs[54].Reg_Num = 82 ;
+	state->TunerRegs[54].Reg_Val = 0x75 ;
+
+	state->TunerRegs[55].Reg_Num = 83 ;
+	state->TunerRegs[55].Reg_Val = 0x00 ;
+
+	state->TunerRegs[56].Reg_Num = 84 ;
+	state->TunerRegs[56].Reg_Val = 0x00 ;
+
+	state->TunerRegs[57].Reg_Num = 85 ;
+	state->TunerRegs[57].Reg_Val = 0x00 ;
+
+	state->TunerRegs[58].Reg_Num = 91 ;
+	state->TunerRegs[58].Reg_Val = 0x70 ;
+
+	state->TunerRegs[59].Reg_Num = 92 ;
+	state->TunerRegs[59].Reg_Val = 0x00 ;
+
+	state->TunerRegs[60].Reg_Num = 93 ;
+	state->TunerRegs[60].Reg_Val = 0x00 ;
+
+	state->TunerRegs[61].Reg_Num = 94 ;
+	state->TunerRegs[61].Reg_Val = 0x00 ;
+
+	state->TunerRegs[62].Reg_Num = 95 ;
+	state->TunerRegs[62].Reg_Val = 0x0C ;
+
+	state->TunerRegs[63].Reg_Num = 96 ;
+	state->TunerRegs[63].Reg_Val = 0x00 ;
+
+	state->TunerRegs[64].Reg_Num = 97 ;
+	state->TunerRegs[64].Reg_Val = 0x00 ;
+
+	state->TunerRegs[65].Reg_Num = 98 ;
+	state->TunerRegs[65].Reg_Val = 0xE2 ;
+
+	state->TunerRegs[66].Reg_Num = 99 ;
+	state->TunerRegs[66].Reg_Val = 0x00 ;
+
+	state->TunerRegs[67].Reg_Num = 100 ;
+	state->TunerRegs[67].Reg_Val = 0x00 ;
+
+	state->TunerRegs[68].Reg_Num = 101 ;
+	state->TunerRegs[68].Reg_Val = 0x12 ;
+
+	state->TunerRegs[69].Reg_Num = 102 ;
+	state->TunerRegs[69].Reg_Val = 0x80 ;
+
+	state->TunerRegs[70].Reg_Num = 103 ;
+	state->TunerRegs[70].Reg_Val = 0x32 ;
+
+	state->TunerRegs[71].Reg_Num = 104 ;
+	state->TunerRegs[71].Reg_Val = 0xB4 ;
+
+	state->TunerRegs[72].Reg_Num = 105 ;
+	state->TunerRegs[72].Reg_Val = 0x60 ;
+
+	state->TunerRegs[73].Reg_Num = 106 ;
+	state->TunerRegs[73].Reg_Val = 0x83 ;
+
+	state->TunerRegs[74].Reg_Num = 107 ;
+	state->TunerRegs[74].Reg_Val = 0x84 ;
+
+	state->TunerRegs[75].Reg_Num = 108 ;
+	state->TunerRegs[75].Reg_Val = 0x9C ;
+
+	state->TunerRegs[76].Reg_Num = 109 ;
+	state->TunerRegs[76].Reg_Val = 0x02 ;
+
+	state->TunerRegs[77].Reg_Num = 110 ;
+	state->TunerRegs[77].Reg_Val = 0x81 ;
+
+	state->TunerRegs[78].Reg_Num = 111 ;
+	state->TunerRegs[78].Reg_Val = 0xC0 ;
+
+	state->TunerRegs[79].Reg_Num = 112 ;
+	state->TunerRegs[79].Reg_Val = 0x10 ;
+
+	state->TunerRegs[80].Reg_Num = 131 ;
+	state->TunerRegs[80].Reg_Val = 0x8A ;
+
+	state->TunerRegs[81].Reg_Num = 132 ;
+	state->TunerRegs[81].Reg_Val = 0x10 ;
+
+	state->TunerRegs[82].Reg_Num = 133 ;
+	state->TunerRegs[82].Reg_Val = 0x24 ;
+
+	state->TunerRegs[83].Reg_Num = 134 ;
+	state->TunerRegs[83].Reg_Val = 0x00 ;
+
+	state->TunerRegs[84].Reg_Num = 135 ;
+	state->TunerRegs[84].Reg_Val = 0x00 ;
+
+	state->TunerRegs[85].Reg_Num = 136 ;
+	state->TunerRegs[85].Reg_Val = 0x7E ;
+
+	state->TunerRegs[86].Reg_Num = 137 ;
+	state->TunerRegs[86].Reg_Val = 0x40 ;
+
+	state->TunerRegs[87].Reg_Num = 138 ;
+	state->TunerRegs[87].Reg_Val = 0x38 ;
+
+	state->TunerRegs[88].Reg_Num = 146 ;
+	state->TunerRegs[88].Reg_Val = 0xF6 ;
+
+	state->TunerRegs[89].Reg_Num = 147 ;
+	state->TunerRegs[89].Reg_Val = 0x1A ;
+
+	state->TunerRegs[90].Reg_Num = 148 ;
+	state->TunerRegs[90].Reg_Val = 0x62 ;
+
+	state->TunerRegs[91].Reg_Num = 149 ;
+	state->TunerRegs[91].Reg_Val = 0x33 ;
+
+	state->TunerRegs[92].Reg_Num = 150 ;
+	state->TunerRegs[92].Reg_Val = 0x80 ;
+
+	state->TunerRegs[93].Reg_Num = 156 ;
+	state->TunerRegs[93].Reg_Val = 0x56 ;
+
+	state->TunerRegs[94].Reg_Num = 157 ;
+	state->TunerRegs[94].Reg_Val = 0x17 ;
+
+	state->TunerRegs[95].Reg_Num = 158 ;
+	state->TunerRegs[95].Reg_Val = 0xA9 ;
+
+	state->TunerRegs[96].Reg_Num = 159 ;
+	state->TunerRegs[96].Reg_Val = 0x00 ;
+
+	state->TunerRegs[97].Reg_Num = 160 ;
+	state->TunerRegs[97].Reg_Val = 0x00 ;
+
+	state->TunerRegs[98].Reg_Num = 161 ;
+	state->TunerRegs[98].Reg_Val = 0x00 ;
+
+	state->TunerRegs[99].Reg_Num = 162 ;
+	state->TunerRegs[99].Reg_Val = 0x40 ;
+
+	state->TunerRegs[100].Reg_Num = 166 ;
+	state->TunerRegs[100].Reg_Val = 0xAE ;
+
+	state->TunerRegs[101].Reg_Num = 167 ;
+	state->TunerRegs[101].Reg_Val = 0x1B ;
+
+	state->TunerRegs[102].Reg_Num = 168 ;
+	state->TunerRegs[102].Reg_Val = 0xF2 ;
+
+	state->TunerRegs[103].Reg_Num = 195 ;
+	state->TunerRegs[103].Reg_Val = 0x00 ;
+
+	return 0 ;
+}
+
+static u16 MXL5005_ControlInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	state->Init_Ctrl_Num = INITCTRL_NUM;
+
+	state->Init_Ctrl[0].Ctrl_Num = DN_IQTN_AMP_CUT ;
+	state->Init_Ctrl[0].size = 1 ;
+	state->Init_Ctrl[0].addr[0] = 73;
+	state->Init_Ctrl[0].bit[0] = 7;
+	state->Init_Ctrl[0].val[0] = 0;
+
+	state->Init_Ctrl[1].Ctrl_Num = BB_MODE ;
+	state->Init_Ctrl[1].size = 1 ;
+	state->Init_Ctrl[1].addr[0] = 53;
+	state->Init_Ctrl[1].bit[0] = 2;
+	state->Init_Ctrl[1].val[0] = 1;
+
+	state->Init_Ctrl[2].Ctrl_Num = BB_BUF ;
+	state->Init_Ctrl[2].size = 2 ;
+	state->Init_Ctrl[2].addr[0] = 53;
+	state->Init_Ctrl[2].bit[0] = 1;
+	state->Init_Ctrl[2].val[0] = 0;
+	state->Init_Ctrl[2].addr[1] = 57;
+	state->Init_Ctrl[2].bit[1] = 0;
+	state->Init_Ctrl[2].val[1] = 1;
+
+	state->Init_Ctrl[3].Ctrl_Num = BB_BUF_OA ;
+	state->Init_Ctrl[3].size = 1 ;
+	state->Init_Ctrl[3].addr[0] = 53;
+	state->Init_Ctrl[3].bit[0] = 0;
+	state->Init_Ctrl[3].val[0] = 0;
+
+	state->Init_Ctrl[4].Ctrl_Num = BB_ALPF_BANDSELECT ;
+	state->Init_Ctrl[4].size = 3 ;
+	state->Init_Ctrl[4].addr[0] = 53;
+	state->Init_Ctrl[4].bit[0] = 5;
+	state->Init_Ctrl[4].val[0] = 0;
+	state->Init_Ctrl[4].addr[1] = 53;
+	state->Init_Ctrl[4].bit[1] = 6;
+	state->Init_Ctrl[4].val[1] = 0;
+	state->Init_Ctrl[4].addr[2] = 53;
+	state->Init_Ctrl[4].bit[2] = 7;
+	state->Init_Ctrl[4].val[2] = 1;
+
+	state->Init_Ctrl[5].Ctrl_Num = BB_IQSWAP ;
+	state->Init_Ctrl[5].size = 1 ;
+	state->Init_Ctrl[5].addr[0] = 59;
+	state->Init_Ctrl[5].bit[0] = 0;
+	state->Init_Ctrl[5].val[0] = 0;
+
+	state->Init_Ctrl[6].Ctrl_Num = BB_DLPF_BANDSEL ;
+	state->Init_Ctrl[6].size = 2 ;
+	state->Init_Ctrl[6].addr[0] = 53;
+	state->Init_Ctrl[6].bit[0] = 3;
+	state->Init_Ctrl[6].val[0] = 0;
+	state->Init_Ctrl[6].addr[1] = 53;
+	state->Init_Ctrl[6].bit[1] = 4;
+	state->Init_Ctrl[6].val[1] = 1;
+
+	state->Init_Ctrl[7].Ctrl_Num = RFSYN_CHP_GAIN ;
+	state->Init_Ctrl[7].size = 4 ;
+	state->Init_Ctrl[7].addr[0] = 22;
+	state->Init_Ctrl[7].bit[0] = 4;
+	state->Init_Ctrl[7].val[0] = 0;
+	state->Init_Ctrl[7].addr[1] = 22;
+	state->Init_Ctrl[7].bit[1] = 5;
+	state->Init_Ctrl[7].val[1] = 1;
+	state->Init_Ctrl[7].addr[2] = 22;
+	state->Init_Ctrl[7].bit[2] = 6;
+	state->Init_Ctrl[7].val[2] = 1;
+	state->Init_Ctrl[7].addr[3] = 22;
+	state->Init_Ctrl[7].bit[3] = 7;
+	state->Init_Ctrl[7].val[3] = 0;
+
+	state->Init_Ctrl[8].Ctrl_Num = RFSYN_EN_CHP_HIGAIN ;
+	state->Init_Ctrl[8].size = 1 ;
+	state->Init_Ctrl[8].addr[0] = 22;
+	state->Init_Ctrl[8].bit[0] = 2;
+	state->Init_Ctrl[8].val[0] = 0;
+
+	state->Init_Ctrl[9].Ctrl_Num = AGC_IF ;
+	state->Init_Ctrl[9].size = 4 ;
+	state->Init_Ctrl[9].addr[0] = 76;
+	state->Init_Ctrl[9].bit[0] = 0;
+	state->Init_Ctrl[9].val[0] = 1;
+	state->Init_Ctrl[9].addr[1] = 76;
+	state->Init_Ctrl[9].bit[1] = 1;
+	state->Init_Ctrl[9].val[1] = 1;
+	state->Init_Ctrl[9].addr[2] = 76;
+	state->Init_Ctrl[9].bit[2] = 2;
+	state->Init_Ctrl[9].val[2] = 0;
+	state->Init_Ctrl[9].addr[3] = 76;
+	state->Init_Ctrl[9].bit[3] = 3;
+	state->Init_Ctrl[9].val[3] = 1;
+
+	state->Init_Ctrl[10].Ctrl_Num = AGC_RF ;
+	state->Init_Ctrl[10].size = 4 ;
+	state->Init_Ctrl[10].addr[0] = 76;
+	state->Init_Ctrl[10].bit[0] = 4;
+	state->Init_Ctrl[10].val[0] = 1;
+	state->Init_Ctrl[10].addr[1] = 76;
+	state->Init_Ctrl[10].bit[1] = 5;
+	state->Init_Ctrl[10].val[1] = 1;
+	state->Init_Ctrl[10].addr[2] = 76;
+	state->Init_Ctrl[10].bit[2] = 6;
+	state->Init_Ctrl[10].val[2] = 0;
+	state->Init_Ctrl[10].addr[3] = 76;
+	state->Init_Ctrl[10].bit[3] = 7;
+	state->Init_Ctrl[10].val[3] = 1;
+
+	state->Init_Ctrl[11].Ctrl_Num = IF_DIVVAL ;
+	state->Init_Ctrl[11].size = 5 ;
+	state->Init_Ctrl[11].addr[0] = 43;
+	state->Init_Ctrl[11].bit[0] = 3;
+	state->Init_Ctrl[11].val[0] = 0;
+	state->Init_Ctrl[11].addr[1] = 43;
+	state->Init_Ctrl[11].bit[1] = 4;
+	state->Init_Ctrl[11].val[1] = 0;
+	state->Init_Ctrl[11].addr[2] = 43;
+	state->Init_Ctrl[11].bit[2] = 5;
+	state->Init_Ctrl[11].val[2] = 0;
+	state->Init_Ctrl[11].addr[3] = 43;
+	state->Init_Ctrl[11].bit[3] = 6;
+	state->Init_Ctrl[11].val[3] = 1;
+	state->Init_Ctrl[11].addr[4] = 43;
+	state->Init_Ctrl[11].bit[4] = 7;
+	state->Init_Ctrl[11].val[4] = 0;
+
+	state->Init_Ctrl[12].Ctrl_Num = IF_VCO_BIAS ;
+	state->Init_Ctrl[12].size = 6 ;
+	state->Init_Ctrl[12].addr[0] = 44;
+	state->Init_Ctrl[12].bit[0] = 2;
+	state->Init_Ctrl[12].val[0] = 0;
+	state->Init_Ctrl[12].addr[1] = 44;
+	state->Init_Ctrl[12].bit[1] = 3;
+	state->Init_Ctrl[12].val[1] = 0;
+	state->Init_Ctrl[12].addr[2] = 44;
+	state->Init_Ctrl[12].bit[2] = 4;
+	state->Init_Ctrl[12].val[2] = 0;
+	state->Init_Ctrl[12].addr[3] = 44;
+	state->Init_Ctrl[12].bit[3] = 5;
+	state->Init_Ctrl[12].val[3] = 1;
+	state->Init_Ctrl[12].addr[4] = 44;
+	state->Init_Ctrl[12].bit[4] = 6;
+	state->Init_Ctrl[12].val[4] = 0;
+	state->Init_Ctrl[12].addr[5] = 44;
+	state->Init_Ctrl[12].bit[5] = 7;
+	state->Init_Ctrl[12].val[5] = 0;
+
+	state->Init_Ctrl[13].Ctrl_Num = CHCAL_INT_MOD_IF ;
+	state->Init_Ctrl[13].size = 7 ;
+	state->Init_Ctrl[13].addr[0] = 11;
+	state->Init_Ctrl[13].bit[0] = 0;
+	state->Init_Ctrl[13].val[0] = 1;
+	state->Init_Ctrl[13].addr[1] = 11;
+	state->Init_Ctrl[13].bit[1] = 1;
+	state->Init_Ctrl[13].val[1] = 0;
+	state->Init_Ctrl[13].addr[2] = 11;
+	state->Init_Ctrl[13].bit[2] = 2;
+	state->Init_Ctrl[13].val[2] = 0;
+	state->Init_Ctrl[13].addr[3] = 11;
+	state->Init_Ctrl[13].bit[3] = 3;
+	state->Init_Ctrl[13].val[3] = 1;
+	state->Init_Ctrl[13].addr[4] = 11;
+	state->Init_Ctrl[13].bit[4] = 4;
+	state->Init_Ctrl[13].val[4] = 1;
+	state->Init_Ctrl[13].addr[5] = 11;
+	state->Init_Ctrl[13].bit[5] = 5;
+	state->Init_Ctrl[13].val[5] = 0;
+	state->Init_Ctrl[13].addr[6] = 11;
+	state->Init_Ctrl[13].bit[6] = 6;
+	state->Init_Ctrl[13].val[6] = 0;
+
+	state->Init_Ctrl[14].Ctrl_Num = CHCAL_FRAC_MOD_IF ;
+	state->Init_Ctrl[14].size = 16 ;
+	state->Init_Ctrl[14].addr[0] = 13;
+	state->Init_Ctrl[14].bit[0] = 0;
+	state->Init_Ctrl[14].val[0] = 0;
+	state->Init_Ctrl[14].addr[1] = 13;
+	state->Init_Ctrl[14].bit[1] = 1;
+	state->Init_Ctrl[14].val[1] = 0;
+	state->Init_Ctrl[14].addr[2] = 13;
+	state->Init_Ctrl[14].bit[2] = 2;
+	state->Init_Ctrl[14].val[2] = 0;
+	state->Init_Ctrl[14].addr[3] = 13;
+	state->Init_Ctrl[14].bit[3] = 3;
+	state->Init_Ctrl[14].val[3] = 0;
+	state->Init_Ctrl[14].addr[4] = 13;
+	state->Init_Ctrl[14].bit[4] = 4;
+	state->Init_Ctrl[14].val[4] = 0;
+	state->Init_Ctrl[14].addr[5] = 13;
+	state->Init_Ctrl[14].bit[5] = 5;
+	state->Init_Ctrl[14].val[5] = 0;
+	state->Init_Ctrl[14].addr[6] = 13;
+	state->Init_Ctrl[14].bit[6] = 6;
+	state->Init_Ctrl[14].val[6] = 0;
+	state->Init_Ctrl[14].addr[7] = 13;
+	state->Init_Ctrl[14].bit[7] = 7;
+	state->Init_Ctrl[14].val[7] = 0;
+	state->Init_Ctrl[14].addr[8] = 12;
+	state->Init_Ctrl[14].bit[8] = 0;
+	state->Init_Ctrl[14].val[8] = 0;
+	state->Init_Ctrl[14].addr[9] = 12;
+	state->Init_Ctrl[14].bit[9] = 1;
+	state->Init_Ctrl[14].val[9] = 0;
+	state->Init_Ctrl[14].addr[10] = 12;
+	state->Init_Ctrl[14].bit[10] = 2;
+	state->Init_Ctrl[14].val[10] = 0;
+	state->Init_Ctrl[14].addr[11] = 12;
+	state->Init_Ctrl[14].bit[11] = 3;
+	state->Init_Ctrl[14].val[11] = 0;
+	state->Init_Ctrl[14].addr[12] = 12;
+	state->Init_Ctrl[14].bit[12] = 4;
+	state->Init_Ctrl[14].val[12] = 0;
+	state->Init_Ctrl[14].addr[13] = 12;
+	state->Init_Ctrl[14].bit[13] = 5;
+	state->Init_Ctrl[14].val[13] = 1;
+	state->Init_Ctrl[14].addr[14] = 12;
+	state->Init_Ctrl[14].bit[14] = 6;
+	state->Init_Ctrl[14].val[14] = 1;
+	state->Init_Ctrl[14].addr[15] = 12;
+	state->Init_Ctrl[14].bit[15] = 7;
+	state->Init_Ctrl[14].val[15] = 0;
+
+	state->Init_Ctrl[15].Ctrl_Num = DRV_RES_SEL ;
+	state->Init_Ctrl[15].size = 3 ;
+	state->Init_Ctrl[15].addr[0] = 147;
+	state->Init_Ctrl[15].bit[0] = 2;
+	state->Init_Ctrl[15].val[0] = 0;
+	state->Init_Ctrl[15].addr[1] = 147;
+	state->Init_Ctrl[15].bit[1] = 3;
+	state->Init_Ctrl[15].val[1] = 1;
+	state->Init_Ctrl[15].addr[2] = 147;
+	state->Init_Ctrl[15].bit[2] = 4;
+	state->Init_Ctrl[15].val[2] = 1;
+
+	state->Init_Ctrl[16].Ctrl_Num = I_DRIVER ;
+	state->Init_Ctrl[16].size = 2 ;
+	state->Init_Ctrl[16].addr[0] = 147;
+	state->Init_Ctrl[16].bit[0] = 0;
+	state->Init_Ctrl[16].val[0] = 0;
+	state->Init_Ctrl[16].addr[1] = 147;
+	state->Init_Ctrl[16].bit[1] = 1;
+	state->Init_Ctrl[16].val[1] = 1;
+
+	state->Init_Ctrl[17].Ctrl_Num = EN_AAF ;
+	state->Init_Ctrl[17].size = 1 ;
+	state->Init_Ctrl[17].addr[0] = 147;
+	state->Init_Ctrl[17].bit[0] = 7;
+	state->Init_Ctrl[17].val[0] = 0;
+
+	state->Init_Ctrl[18].Ctrl_Num = EN_3P ;
+	state->Init_Ctrl[18].size = 1 ;
+	state->Init_Ctrl[18].addr[0] = 147;
+	state->Init_Ctrl[18].bit[0] = 6;
+	state->Init_Ctrl[18].val[0] = 0;
+
+	state->Init_Ctrl[19].Ctrl_Num = EN_AUX_3P ;
+	state->Init_Ctrl[19].size = 1 ;
+	state->Init_Ctrl[19].addr[0] = 156;
+	state->Init_Ctrl[19].bit[0] = 0;
+	state->Init_Ctrl[19].val[0] = 0;
+
+	state->Init_Ctrl[20].Ctrl_Num = SEL_AAF_BAND ;
+	state->Init_Ctrl[20].size = 1 ;
+	state->Init_Ctrl[20].addr[0] = 147;
+	state->Init_Ctrl[20].bit[0] = 5;
+	state->Init_Ctrl[20].val[0] = 0;
+
+	state->Init_Ctrl[21].Ctrl_Num = SEQ_ENCLK16_CLK_OUT ;
+	state->Init_Ctrl[21].size = 1 ;
+	state->Init_Ctrl[21].addr[0] = 137;
+	state->Init_Ctrl[21].bit[0] = 4;
+	state->Init_Ctrl[21].val[0] = 0;
+
+	state->Init_Ctrl[22].Ctrl_Num = SEQ_SEL4_16B ;
+	state->Init_Ctrl[22].size = 1 ;
+	state->Init_Ctrl[22].addr[0] = 137;
+	state->Init_Ctrl[22].bit[0] = 7;
+	state->Init_Ctrl[22].val[0] = 0;
+
+	state->Init_Ctrl[23].Ctrl_Num = XTAL_CAPSELECT ;
+	state->Init_Ctrl[23].size = 1 ;
+	state->Init_Ctrl[23].addr[0] = 91;
+	state->Init_Ctrl[23].bit[0] = 5;
+	state->Init_Ctrl[23].val[0] = 1;
+
+	state->Init_Ctrl[24].Ctrl_Num = IF_SEL_DBL ;
+	state->Init_Ctrl[24].size = 1 ;
+	state->Init_Ctrl[24].addr[0] = 43;
+	state->Init_Ctrl[24].bit[0] = 0;
+	state->Init_Ctrl[24].val[0] = 1;
+
+	state->Init_Ctrl[25].Ctrl_Num = RFSYN_R_DIV ;
+	state->Init_Ctrl[25].size = 2 ;
+	state->Init_Ctrl[25].addr[0] = 22;
+	state->Init_Ctrl[25].bit[0] = 0;
+	state->Init_Ctrl[25].val[0] = 1;
+	state->Init_Ctrl[25].addr[1] = 22;
+	state->Init_Ctrl[25].bit[1] = 1;
+	state->Init_Ctrl[25].val[1] = 1;
+
+	state->Init_Ctrl[26].Ctrl_Num = SEQ_EXTSYNTHCALIF ;
+	state->Init_Ctrl[26].size = 1 ;
+	state->Init_Ctrl[26].addr[0] = 134;
+	state->Init_Ctrl[26].bit[0] = 2;
+	state->Init_Ctrl[26].val[0] = 0;
+
+	state->Init_Ctrl[27].Ctrl_Num = SEQ_EXTDCCAL ;
+	state->Init_Ctrl[27].size = 1 ;
+	state->Init_Ctrl[27].addr[0] = 137;
+	state->Init_Ctrl[27].bit[0] = 3;
+	state->Init_Ctrl[27].val[0] = 0;
+
+	state->Init_Ctrl[28].Ctrl_Num = AGC_EN_RSSI ;
+	state->Init_Ctrl[28].size = 1 ;
+	state->Init_Ctrl[28].addr[0] = 77;
+	state->Init_Ctrl[28].bit[0] = 7;
+	state->Init_Ctrl[28].val[0] = 0;
+
+	state->Init_Ctrl[29].Ctrl_Num = RFA_ENCLKRFAGC ;
+	state->Init_Ctrl[29].size = 1 ;
+	state->Init_Ctrl[29].addr[0] = 166;
+	state->Init_Ctrl[29].bit[0] = 7;
+	state->Init_Ctrl[29].val[0] = 1;
+
+	state->Init_Ctrl[30].Ctrl_Num = RFA_RSSI_REFH ;
+	state->Init_Ctrl[30].size = 3 ;
+	state->Init_Ctrl[30].addr[0] = 166;
+	state->Init_Ctrl[30].bit[0] = 0;
+	state->Init_Ctrl[30].val[0] = 0;
+	state->Init_Ctrl[30].addr[1] = 166;
+	state->Init_Ctrl[30].bit[1] = 1;
+	state->Init_Ctrl[30].val[1] = 1;
+	state->Init_Ctrl[30].addr[2] = 166;
+	state->Init_Ctrl[30].bit[2] = 2;
+	state->Init_Ctrl[30].val[2] = 1;
+
+	state->Init_Ctrl[31].Ctrl_Num = RFA_RSSI_REF ;
+	state->Init_Ctrl[31].size = 3 ;
+	state->Init_Ctrl[31].addr[0] = 166;
+	state->Init_Ctrl[31].bit[0] = 3;
+	state->Init_Ctrl[31].val[0] = 1;
+	state->Init_Ctrl[31].addr[1] = 166;
+	state->Init_Ctrl[31].bit[1] = 4;
+	state->Init_Ctrl[31].val[1] = 0;
+	state->Init_Ctrl[31].addr[2] = 166;
+	state->Init_Ctrl[31].bit[2] = 5;
+	state->Init_Ctrl[31].val[2] = 1;
+
+	state->Init_Ctrl[32].Ctrl_Num = RFA_RSSI_REFL ;
+	state->Init_Ctrl[32].size = 3 ;
+	state->Init_Ctrl[32].addr[0] = 167;
+	state->Init_Ctrl[32].bit[0] = 0;
+	state->Init_Ctrl[32].val[0] = 1;
+	state->Init_Ctrl[32].addr[1] = 167;
+	state->Init_Ctrl[32].bit[1] = 1;
+	state->Init_Ctrl[32].val[1] = 1;
+	state->Init_Ctrl[32].addr[2] = 167;
+	state->Init_Ctrl[32].bit[2] = 2;
+	state->Init_Ctrl[32].val[2] = 0;
+
+	state->Init_Ctrl[33].Ctrl_Num = RFA_FLR ;
+	state->Init_Ctrl[33].size = 4 ;
+	state->Init_Ctrl[33].addr[0] = 168;
+	state->Init_Ctrl[33].bit[0] = 0;
+	state->Init_Ctrl[33].val[0] = 0;
+	state->Init_Ctrl[33].addr[1] = 168;
+	state->Init_Ctrl[33].bit[1] = 1;
+	state->Init_Ctrl[33].val[1] = 1;
+	state->Init_Ctrl[33].addr[2] = 168;
+	state->Init_Ctrl[33].bit[2] = 2;
+	state->Init_Ctrl[33].val[2] = 0;
+	state->Init_Ctrl[33].addr[3] = 168;
+	state->Init_Ctrl[33].bit[3] = 3;
+	state->Init_Ctrl[33].val[3] = 0;
+
+	state->Init_Ctrl[34].Ctrl_Num = RFA_CEIL ;
+	state->Init_Ctrl[34].size = 4 ;
+	state->Init_Ctrl[34].addr[0] = 168;
+	state->Init_Ctrl[34].bit[0] = 4;
+	state->Init_Ctrl[34].val[0] = 1;
+	state->Init_Ctrl[34].addr[1] = 168;
+	state->Init_Ctrl[34].bit[1] = 5;
+	state->Init_Ctrl[34].val[1] = 1;
+	state->Init_Ctrl[34].addr[2] = 168;
+	state->Init_Ctrl[34].bit[2] = 6;
+	state->Init_Ctrl[34].val[2] = 1;
+	state->Init_Ctrl[34].addr[3] = 168;
+	state->Init_Ctrl[34].bit[3] = 7;
+	state->Init_Ctrl[34].val[3] = 1;
+
+	state->Init_Ctrl[35].Ctrl_Num = SEQ_EXTIQFSMPULSE ;
+	state->Init_Ctrl[35].size = 1 ;
+	state->Init_Ctrl[35].addr[0] = 135;
+	state->Init_Ctrl[35].bit[0] = 0;
+	state->Init_Ctrl[35].val[0] = 0;
+
+	state->Init_Ctrl[36].Ctrl_Num = OVERRIDE_1 ;
+	state->Init_Ctrl[36].size = 1 ;
+	state->Init_Ctrl[36].addr[0] = 56;
+	state->Init_Ctrl[36].bit[0] = 3;
+	state->Init_Ctrl[36].val[0] = 0;
+
+	state->Init_Ctrl[37].Ctrl_Num = BB_INITSTATE_DLPF_TUNE ;
+	state->Init_Ctrl[37].size = 7 ;
+	state->Init_Ctrl[37].addr[0] = 59;
+	state->Init_Ctrl[37].bit[0] = 1;
+	state->Init_Ctrl[37].val[0] = 0;
+	state->Init_Ctrl[37].addr[1] = 59;
+	state->Init_Ctrl[37].bit[1] = 2;
+	state->Init_Ctrl[37].val[1] = 0;
+	state->Init_Ctrl[37].addr[2] = 59;
+	state->Init_Ctrl[37].bit[2] = 3;
+	state->Init_Ctrl[37].val[2] = 0;
+	state->Init_Ctrl[37].addr[3] = 59;
+	state->Init_Ctrl[37].bit[3] = 4;
+	state->Init_Ctrl[37].val[3] = 0;
+	state->Init_Ctrl[37].addr[4] = 59;
+	state->Init_Ctrl[37].bit[4] = 5;
+	state->Init_Ctrl[37].val[4] = 0;
+	state->Init_Ctrl[37].addr[5] = 59;
+	state->Init_Ctrl[37].bit[5] = 6;
+	state->Init_Ctrl[37].val[5] = 0;
+	state->Init_Ctrl[37].addr[6] = 59;
+	state->Init_Ctrl[37].bit[6] = 7;
+	state->Init_Ctrl[37].val[6] = 0;
+
+	state->Init_Ctrl[38].Ctrl_Num = TG_R_DIV ;
+	state->Init_Ctrl[38].size = 6 ;
+	state->Init_Ctrl[38].addr[0] = 32;
+	state->Init_Ctrl[38].bit[0] = 2;
+	state->Init_Ctrl[38].val[0] = 0;
+	state->Init_Ctrl[38].addr[1] = 32;
+	state->Init_Ctrl[38].bit[1] = 3;
+	state->Init_Ctrl[38].val[1] = 0;
+	state->Init_Ctrl[38].addr[2] = 32;
+	state->Init_Ctrl[38].bit[2] = 4;
+	state->Init_Ctrl[38].val[2] = 0;
+	state->Init_Ctrl[38].addr[3] = 32;
+	state->Init_Ctrl[38].bit[3] = 5;
+	state->Init_Ctrl[38].val[3] = 0;
+	state->Init_Ctrl[38].addr[4] = 32;
+	state->Init_Ctrl[38].bit[4] = 6;
+	state->Init_Ctrl[38].val[4] = 1;
+	state->Init_Ctrl[38].addr[5] = 32;
+	state->Init_Ctrl[38].bit[5] = 7;
+	state->Init_Ctrl[38].val[5] = 0;
+
+	state->Init_Ctrl[39].Ctrl_Num = EN_CHP_LIN_B ;
+	state->Init_Ctrl[39].size = 1 ;
+	state->Init_Ctrl[39].addr[0] = 25;
+	state->Init_Ctrl[39].bit[0] = 3;
+	state->Init_Ctrl[39].val[0] = 1;
+
+
+	state->CH_Ctrl_Num = CHCTRL_NUM ;
+
+	state->CH_Ctrl[0].Ctrl_Num = DN_POLY ;
+	state->CH_Ctrl[0].size = 2 ;
+	state->CH_Ctrl[0].addr[0] = 68;
+	state->CH_Ctrl[0].bit[0] = 6;
+	state->CH_Ctrl[0].val[0] = 1;
+	state->CH_Ctrl[0].addr[1] = 68;
+	state->CH_Ctrl[0].bit[1] = 7;
+	state->CH_Ctrl[0].val[1] = 1;
+
+	state->CH_Ctrl[1].Ctrl_Num = DN_RFGAIN ;
+	state->CH_Ctrl[1].size = 2 ;
+	state->CH_Ctrl[1].addr[0] = 70;
+	state->CH_Ctrl[1].bit[0] = 6;
+	state->CH_Ctrl[1].val[0] = 1;
+	state->CH_Ctrl[1].addr[1] = 70;
+	state->CH_Ctrl[1].bit[1] = 7;
+	state->CH_Ctrl[1].val[1] = 0;
+
+	state->CH_Ctrl[2].Ctrl_Num = DN_CAP_RFLPF ;
+	state->CH_Ctrl[2].size = 9 ;
+	state->CH_Ctrl[2].addr[0] = 69;
+	state->CH_Ctrl[2].bit[0] = 5;
+	state->CH_Ctrl[2].val[0] = 0;
+	state->CH_Ctrl[2].addr[1] = 69;
+	state->CH_Ctrl[2].bit[1] = 6;
+	state->CH_Ctrl[2].val[1] = 0;
+	state->CH_Ctrl[2].addr[2] = 69;
+	state->CH_Ctrl[2].bit[2] = 7;
+	state->CH_Ctrl[2].val[2] = 0;
+	state->CH_Ctrl[2].addr[3] = 68;
+	state->CH_Ctrl[2].bit[3] = 0;
+	state->CH_Ctrl[2].val[3] = 0;
+	state->CH_Ctrl[2].addr[4] = 68;
+	state->CH_Ctrl[2].bit[4] = 1;
+	state->CH_Ctrl[2].val[4] = 0;
+	state->CH_Ctrl[2].addr[5] = 68;
+	state->CH_Ctrl[2].bit[5] = 2;
+	state->CH_Ctrl[2].val[5] = 0;
+	state->CH_Ctrl[2].addr[6] = 68;
+	state->CH_Ctrl[2].bit[6] = 3;
+	state->CH_Ctrl[2].val[6] = 0;
+	state->CH_Ctrl[2].addr[7] = 68;
+	state->CH_Ctrl[2].bit[7] = 4;
+	state->CH_Ctrl[2].val[7] = 0;
+	state->CH_Ctrl[2].addr[8] = 68;
+	state->CH_Ctrl[2].bit[8] = 5;
+	state->CH_Ctrl[2].val[8] = 0;
+
+	state->CH_Ctrl[3].Ctrl_Num = DN_EN_VHFUHFBAR ;
+	state->CH_Ctrl[3].size = 1 ;
+	state->CH_Ctrl[3].addr[0] = 70;
+	state->CH_Ctrl[3].bit[0] = 5;
+	state->CH_Ctrl[3].val[0] = 0;
+
+	state->CH_Ctrl[4].Ctrl_Num = DN_GAIN_ADJUST ;
+	state->CH_Ctrl[4].size = 3 ;
+	state->CH_Ctrl[4].addr[0] = 73;
+	state->CH_Ctrl[4].bit[0] = 4;
+	state->CH_Ctrl[4].val[0] = 0;
+	state->CH_Ctrl[4].addr[1] = 73;
+	state->CH_Ctrl[4].bit[1] = 5;
+	state->CH_Ctrl[4].val[1] = 1;
+	state->CH_Ctrl[4].addr[2] = 73;
+	state->CH_Ctrl[4].bit[2] = 6;
+	state->CH_Ctrl[4].val[2] = 0;
+
+	state->CH_Ctrl[5].Ctrl_Num = DN_IQTNBUF_AMP ;
+	state->CH_Ctrl[5].size = 4 ;
+	state->CH_Ctrl[5].addr[0] = 70;
+	state->CH_Ctrl[5].bit[0] = 0;
+	state->CH_Ctrl[5].val[0] = 0;
+	state->CH_Ctrl[5].addr[1] = 70;
+	state->CH_Ctrl[5].bit[1] = 1;
+	state->CH_Ctrl[5].val[1] = 0;
+	state->CH_Ctrl[5].addr[2] = 70;
+	state->CH_Ctrl[5].bit[2] = 2;
+	state->CH_Ctrl[5].val[2] = 0;
+	state->CH_Ctrl[5].addr[3] = 70;
+	state->CH_Ctrl[5].bit[3] = 3;
+	state->CH_Ctrl[5].val[3] = 0;
+
+	state->CH_Ctrl[6].Ctrl_Num = DN_IQTNGNBFBIAS_BST ;
+	state->CH_Ctrl[6].size = 1 ;
+	state->CH_Ctrl[6].addr[0] = 70;
+	state->CH_Ctrl[6].bit[0] = 4;
+	state->CH_Ctrl[6].val[0] = 1;
+
+	state->CH_Ctrl[7].Ctrl_Num = RFSYN_EN_OUTMUX ;
+	state->CH_Ctrl[7].size = 1 ;
+	state->CH_Ctrl[7].addr[0] = 111;
+	state->CH_Ctrl[7].bit[0] = 4;
+	state->CH_Ctrl[7].val[0] = 0;
+
+	state->CH_Ctrl[8].Ctrl_Num = RFSYN_SEL_VCO_OUT ;
+	state->CH_Ctrl[8].size = 1 ;
+	state->CH_Ctrl[8].addr[0] = 111;
+	state->CH_Ctrl[8].bit[0] = 7;
+	state->CH_Ctrl[8].val[0] = 1;
+
+	state->CH_Ctrl[9].Ctrl_Num = RFSYN_SEL_VCO_HI ;
+	state->CH_Ctrl[9].size = 1 ;
+	state->CH_Ctrl[9].addr[0] = 111;
+	state->CH_Ctrl[9].bit[0] = 6;
+	state->CH_Ctrl[9].val[0] = 1;
+
+	state->CH_Ctrl[10].Ctrl_Num = RFSYN_SEL_DIVM ;
+	state->CH_Ctrl[10].size = 1 ;
+	state->CH_Ctrl[10].addr[0] = 111;
+	state->CH_Ctrl[10].bit[0] = 5;
+	state->CH_Ctrl[10].val[0] = 0;
+
+	state->CH_Ctrl[11].Ctrl_Num = RFSYN_RF_DIV_BIAS ;
+	state->CH_Ctrl[11].size = 2 ;
+	state->CH_Ctrl[11].addr[0] = 110;
+	state->CH_Ctrl[11].bit[0] = 0;
+	state->CH_Ctrl[11].val[0] = 1;
+	state->CH_Ctrl[11].addr[1] = 110;
+	state->CH_Ctrl[11].bit[1] = 1;
+	state->CH_Ctrl[11].val[1] = 0;
+
+	state->CH_Ctrl[12].Ctrl_Num = DN_SEL_FREQ ;
+	state->CH_Ctrl[12].size = 3 ;
+	state->CH_Ctrl[12].addr[0] = 69;
+	state->CH_Ctrl[12].bit[0] = 2;
+	state->CH_Ctrl[12].val[0] = 0;
+	state->CH_Ctrl[12].addr[1] = 69;
+	state->CH_Ctrl[12].bit[1] = 3;
+	state->CH_Ctrl[12].val[1] = 0;
+	state->CH_Ctrl[12].addr[2] = 69;
+	state->CH_Ctrl[12].bit[2] = 4;
+	state->CH_Ctrl[12].val[2] = 0;
+
+	state->CH_Ctrl[13].Ctrl_Num = RFSYN_VCO_BIAS ;
+	state->CH_Ctrl[13].size = 6 ;
+	state->CH_Ctrl[13].addr[0] = 110;
+	state->CH_Ctrl[13].bit[0] = 2;
+	state->CH_Ctrl[13].val[0] = 0;
+	state->CH_Ctrl[13].addr[1] = 110;
+	state->CH_Ctrl[13].bit[1] = 3;
+	state->CH_Ctrl[13].val[1] = 0;
+	state->CH_Ctrl[13].addr[2] = 110;
+	state->CH_Ctrl[13].bit[2] = 4;
+	state->CH_Ctrl[13].val[2] = 0;
+	state->CH_Ctrl[13].addr[3] = 110;
+	state->CH_Ctrl[13].bit[3] = 5;
+	state->CH_Ctrl[13].val[3] = 0;
+	state->CH_Ctrl[13].addr[4] = 110;
+	state->CH_Ctrl[13].bit[4] = 6;
+	state->CH_Ctrl[13].val[4] = 0;
+	state->CH_Ctrl[13].addr[5] = 110;
+	state->CH_Ctrl[13].bit[5] = 7;
+	state->CH_Ctrl[13].val[5] = 1;
+
+	state->CH_Ctrl[14].Ctrl_Num = CHCAL_INT_MOD_RF ;
+	state->CH_Ctrl[14].size = 7 ;
+	state->CH_Ctrl[14].addr[0] = 14;
+	state->CH_Ctrl[14].bit[0] = 0;
+	state->CH_Ctrl[14].val[0] = 0;
+	state->CH_Ctrl[14].addr[1] = 14;
+	state->CH_Ctrl[14].bit[1] = 1;
+	state->CH_Ctrl[14].val[1] = 0;
+	state->CH_Ctrl[14].addr[2] = 14;
+	state->CH_Ctrl[14].bit[2] = 2;
+	state->CH_Ctrl[14].val[2] = 0;
+	state->CH_Ctrl[14].addr[3] = 14;
+	state->CH_Ctrl[14].bit[3] = 3;
+	state->CH_Ctrl[14].val[3] = 0;
+	state->CH_Ctrl[14].addr[4] = 14;
+	state->CH_Ctrl[14].bit[4] = 4;
+	state->CH_Ctrl[14].val[4] = 0;
+	state->CH_Ctrl[14].addr[5] = 14;
+	state->CH_Ctrl[14].bit[5] = 5;
+	state->CH_Ctrl[14].val[5] = 0;
+	state->CH_Ctrl[14].addr[6] = 14;
+	state->CH_Ctrl[14].bit[6] = 6;
+	state->CH_Ctrl[14].val[6] = 0;
+
+	state->CH_Ctrl[15].Ctrl_Num = CHCAL_FRAC_MOD_RF ;
+	state->CH_Ctrl[15].size = 18 ;
+	state->CH_Ctrl[15].addr[0] = 17;
+	state->CH_Ctrl[15].bit[0] = 6;
+	state->CH_Ctrl[15].val[0] = 0;
+	state->CH_Ctrl[15].addr[1] = 17;
+	state->CH_Ctrl[15].bit[1] = 7;
+	state->CH_Ctrl[15].val[1] = 0;
+	state->CH_Ctrl[15].addr[2] = 16;
+	state->CH_Ctrl[15].bit[2] = 0;
+	state->CH_Ctrl[15].val[2] = 0;
+	state->CH_Ctrl[15].addr[3] = 16;
+	state->CH_Ctrl[15].bit[3] = 1;
+	state->CH_Ctrl[15].val[3] = 0;
+	state->CH_Ctrl[15].addr[4] = 16;
+	state->CH_Ctrl[15].bit[4] = 2;
+	state->CH_Ctrl[15].val[4] = 0;
+	state->CH_Ctrl[15].addr[5] = 16;
+	state->CH_Ctrl[15].bit[5] = 3;
+	state->CH_Ctrl[15].val[5] = 0;
+	state->CH_Ctrl[15].addr[6] = 16;
+	state->CH_Ctrl[15].bit[6] = 4;
+	state->CH_Ctrl[15].val[6] = 0;
+	state->CH_Ctrl[15].addr[7] = 16;
+	state->CH_Ctrl[15].bit[7] = 5;
+	state->CH_Ctrl[15].val[7] = 0;
+	state->CH_Ctrl[15].addr[8] = 16;
+	state->CH_Ctrl[15].bit[8] = 6;
+	state->CH_Ctrl[15].val[8] = 0;
+	state->CH_Ctrl[15].addr[9] = 16;
+	state->CH_Ctrl[15].bit[9] = 7;
+	state->CH_Ctrl[15].val[9] = 0;
+	state->CH_Ctrl[15].addr[10] = 15;
+	state->CH_Ctrl[15].bit[10] = 0;
+	state->CH_Ctrl[15].val[10] = 0;
+	state->CH_Ctrl[15].addr[11] = 15;
+	state->CH_Ctrl[15].bit[11] = 1;
+	state->CH_Ctrl[15].val[11] = 0;
+	state->CH_Ctrl[15].addr[12] = 15;
+	state->CH_Ctrl[15].bit[12] = 2;
+	state->CH_Ctrl[15].val[12] = 0;
+	state->CH_Ctrl[15].addr[13] = 15;
+	state->CH_Ctrl[15].bit[13] = 3;
+	state->CH_Ctrl[15].val[13] = 0;
+	state->CH_Ctrl[15].addr[14] = 15;
+	state->CH_Ctrl[15].bit[14] = 4;
+	state->CH_Ctrl[15].val[14] = 0;
+	state->CH_Ctrl[15].addr[15] = 15;
+	state->CH_Ctrl[15].bit[15] = 5;
+	state->CH_Ctrl[15].val[15] = 0;
+	state->CH_Ctrl[15].addr[16] = 15;
+	state->CH_Ctrl[15].bit[16] = 6;
+	state->CH_Ctrl[15].val[16] = 1;
+	state->CH_Ctrl[15].addr[17] = 15;
+	state->CH_Ctrl[15].bit[17] = 7;
+	state->CH_Ctrl[15].val[17] = 1;
+
+	state->CH_Ctrl[16].Ctrl_Num = RFSYN_LPF_R ;
+	state->CH_Ctrl[16].size = 5 ;
+	state->CH_Ctrl[16].addr[0] = 112;
+	state->CH_Ctrl[16].bit[0] = 0;
+	state->CH_Ctrl[16].val[0] = 0;
+	state->CH_Ctrl[16].addr[1] = 112;
+	state->CH_Ctrl[16].bit[1] = 1;
+	state->CH_Ctrl[16].val[1] = 0;
+	state->CH_Ctrl[16].addr[2] = 112;
+	state->CH_Ctrl[16].bit[2] = 2;
+	state->CH_Ctrl[16].val[2] = 0;
+	state->CH_Ctrl[16].addr[3] = 112;
+	state->CH_Ctrl[16].bit[3] = 3;
+	state->CH_Ctrl[16].val[3] = 0;
+	state->CH_Ctrl[16].addr[4] = 112;
+	state->CH_Ctrl[16].bit[4] = 4;
+	state->CH_Ctrl[16].val[4] = 1;
+
+	state->CH_Ctrl[17].Ctrl_Num = CHCAL_EN_INT_RF ;
+	state->CH_Ctrl[17].size = 1 ;
+	state->CH_Ctrl[17].addr[0] = 14;
+	state->CH_Ctrl[17].bit[0] = 7;
+	state->CH_Ctrl[17].val[0] = 0;
+
+	state->CH_Ctrl[18].Ctrl_Num = TG_LO_DIVVAL ;
+	state->CH_Ctrl[18].size = 4 ;
+	state->CH_Ctrl[18].addr[0] = 107;
+	state->CH_Ctrl[18].bit[0] = 3;
+	state->CH_Ctrl[18].val[0] = 0;
+	state->CH_Ctrl[18].addr[1] = 107;
+	state->CH_Ctrl[18].bit[1] = 4;
+	state->CH_Ctrl[18].val[1] = 0;
+	state->CH_Ctrl[18].addr[2] = 107;
+	state->CH_Ctrl[18].bit[2] = 5;
+	state->CH_Ctrl[18].val[2] = 0;
+	state->CH_Ctrl[18].addr[3] = 107;
+	state->CH_Ctrl[18].bit[3] = 6;
+	state->CH_Ctrl[18].val[3] = 0;
+
+	state->CH_Ctrl[19].Ctrl_Num = TG_LO_SELVAL ;
+	state->CH_Ctrl[19].size = 3 ;
+	state->CH_Ctrl[19].addr[0] = 107;
+	state->CH_Ctrl[19].bit[0] = 7;
+	state->CH_Ctrl[19].val[0] = 1;
+	state->CH_Ctrl[19].addr[1] = 106;
+	state->CH_Ctrl[19].bit[1] = 0;
+	state->CH_Ctrl[19].val[1] = 1;
+	state->CH_Ctrl[19].addr[2] = 106;
+	state->CH_Ctrl[19].bit[2] = 1;
+	state->CH_Ctrl[19].val[2] = 1;
+
+	state->CH_Ctrl[20].Ctrl_Num = TG_DIV_VAL ;
+	state->CH_Ctrl[20].size = 11 ;
+	state->CH_Ctrl[20].addr[0] = 109;
+	state->CH_Ctrl[20].bit[0] = 2;
+	state->CH_Ctrl[20].val[0] = 0;
+	state->CH_Ctrl[20].addr[1] = 109;
+	state->CH_Ctrl[20].bit[1] = 3;
+	state->CH_Ctrl[20].val[1] = 0;
+	state->CH_Ctrl[20].addr[2] = 109;
+	state->CH_Ctrl[20].bit[2] = 4;
+	state->CH_Ctrl[20].val[2] = 0;
+	state->CH_Ctrl[20].addr[3] = 109;
+	state->CH_Ctrl[20].bit[3] = 5;
+	state->CH_Ctrl[20].val[3] = 0;
+	state->CH_Ctrl[20].addr[4] = 109;
+	state->CH_Ctrl[20].bit[4] = 6;
+	state->CH_Ctrl[20].val[4] = 0;
+	state->CH_Ctrl[20].addr[5] = 109;
+	state->CH_Ctrl[20].bit[5] = 7;
+	state->CH_Ctrl[20].val[5] = 0;
+	state->CH_Ctrl[20].addr[6] = 108;
+	state->CH_Ctrl[20].bit[6] = 0;
+	state->CH_Ctrl[20].val[6] = 0;
+	state->CH_Ctrl[20].addr[7] = 108;
+	state->CH_Ctrl[20].bit[7] = 1;
+	state->CH_Ctrl[20].val[7] = 0;
+	state->CH_Ctrl[20].addr[8] = 108;
+	state->CH_Ctrl[20].bit[8] = 2;
+	state->CH_Ctrl[20].val[8] = 1;
+	state->CH_Ctrl[20].addr[9] = 108;
+	state->CH_Ctrl[20].bit[9] = 3;
+	state->CH_Ctrl[20].val[9] = 1;
+	state->CH_Ctrl[20].addr[10] = 108;
+	state->CH_Ctrl[20].bit[10] = 4;
+	state->CH_Ctrl[20].val[10] = 1;
+
+	state->CH_Ctrl[21].Ctrl_Num = TG_VCO_BIAS ;
+	state->CH_Ctrl[21].size = 6 ;
+	state->CH_Ctrl[21].addr[0] = 106;
+	state->CH_Ctrl[21].bit[0] = 2;
+	state->CH_Ctrl[21].val[0] = 0;
+	state->CH_Ctrl[21].addr[1] = 106;
+	state->CH_Ctrl[21].bit[1] = 3;
+	state->CH_Ctrl[21].val[1] = 0;
+	state->CH_Ctrl[21].addr[2] = 106;
+	state->CH_Ctrl[21].bit[2] = 4;
+	state->CH_Ctrl[21].val[2] = 0;
+	state->CH_Ctrl[21].addr[3] = 106;
+	state->CH_Ctrl[21].bit[3] = 5;
+	state->CH_Ctrl[21].val[3] = 0;
+	state->CH_Ctrl[21].addr[4] = 106;
+	state->CH_Ctrl[21].bit[4] = 6;
+	state->CH_Ctrl[21].val[4] = 0;
+	state->CH_Ctrl[21].addr[5] = 106;
+	state->CH_Ctrl[21].bit[5] = 7;
+	state->CH_Ctrl[21].val[5] = 1;
+
+	state->CH_Ctrl[22].Ctrl_Num = SEQ_EXTPOWERUP ;
+	state->CH_Ctrl[22].size = 1 ;
+	state->CH_Ctrl[22].addr[0] = 138;
+	state->CH_Ctrl[22].bit[0] = 4;
+	state->CH_Ctrl[22].val[0] = 1;
+
+	state->CH_Ctrl[23].Ctrl_Num = OVERRIDE_2 ;
+	state->CH_Ctrl[23].size = 1 ;
+	state->CH_Ctrl[23].addr[0] = 17;
+	state->CH_Ctrl[23].bit[0] = 5;
+	state->CH_Ctrl[23].val[0] = 0;
+
+	state->CH_Ctrl[24].Ctrl_Num = OVERRIDE_3 ;
+	state->CH_Ctrl[24].size = 1 ;
+	state->CH_Ctrl[24].addr[0] = 111;
+	state->CH_Ctrl[24].bit[0] = 3;
+	state->CH_Ctrl[24].val[0] = 0;
+
+	state->CH_Ctrl[25].Ctrl_Num = OVERRIDE_4 ;
+	state->CH_Ctrl[25].size = 1 ;
+	state->CH_Ctrl[25].addr[0] = 112;
+	state->CH_Ctrl[25].bit[0] = 7;
+	state->CH_Ctrl[25].val[0] = 0;
+
+	state->CH_Ctrl[26].Ctrl_Num = SEQ_FSM_PULSE ;
+	state->CH_Ctrl[26].size = 1 ;
+	state->CH_Ctrl[26].addr[0] = 136;
+	state->CH_Ctrl[26].bit[0] = 7;
+	state->CH_Ctrl[26].val[0] = 0;
+
+	state->CH_Ctrl[27].Ctrl_Num = GPIO_4B ;
+	state->CH_Ctrl[27].size = 1 ;
+	state->CH_Ctrl[27].addr[0] = 149;
+	state->CH_Ctrl[27].bit[0] = 7;
+	state->CH_Ctrl[27].val[0] = 0;
+
+	state->CH_Ctrl[28].Ctrl_Num = GPIO_3B ;
+	state->CH_Ctrl[28].size = 1 ;
+	state->CH_Ctrl[28].addr[0] = 149;
+	state->CH_Ctrl[28].bit[0] = 6;
+	state->CH_Ctrl[28].val[0] = 0;
+
+	state->CH_Ctrl[29].Ctrl_Num = GPIO_4 ;
+	state->CH_Ctrl[29].size = 1 ;
+	state->CH_Ctrl[29].addr[0] = 149;
+	state->CH_Ctrl[29].bit[0] = 5;
+	state->CH_Ctrl[29].val[0] = 1;
+
+	state->CH_Ctrl[30].Ctrl_Num = GPIO_3 ;
+	state->CH_Ctrl[30].size = 1 ;
+	state->CH_Ctrl[30].addr[0] = 149;
+	state->CH_Ctrl[30].bit[0] = 4;
+	state->CH_Ctrl[30].val[0] = 1;
+
+	state->CH_Ctrl[31].Ctrl_Num = GPIO_1B ;
+	state->CH_Ctrl[31].size = 1 ;
+	state->CH_Ctrl[31].addr[0] = 149;
+	state->CH_Ctrl[31].bit[0] = 3;
+	state->CH_Ctrl[31].val[0] = 0;
+
+	state->CH_Ctrl[32].Ctrl_Num = DAC_A_ENABLE ;
+	state->CH_Ctrl[32].size = 1 ;
+	state->CH_Ctrl[32].addr[0] = 93;
+	state->CH_Ctrl[32].bit[0] = 1;
+	state->CH_Ctrl[32].val[0] = 0;
+
+	state->CH_Ctrl[33].Ctrl_Num = DAC_B_ENABLE ;
+	state->CH_Ctrl[33].size = 1 ;
+	state->CH_Ctrl[33].addr[0] = 93;
+	state->CH_Ctrl[33].bit[0] = 0;
+	state->CH_Ctrl[33].val[0] = 0;
+
+	state->CH_Ctrl[34].Ctrl_Num = DAC_DIN_A ;
+	state->CH_Ctrl[34].size = 6 ;
+	state->CH_Ctrl[34].addr[0] = 92;
+	state->CH_Ctrl[34].bit[0] = 2;
+	state->CH_Ctrl[34].val[0] = 0;
+	state->CH_Ctrl[34].addr[1] = 92;
+	state->CH_Ctrl[34].bit[1] = 3;
+	state->CH_Ctrl[34].val[1] = 0;
+	state->CH_Ctrl[34].addr[2] = 92;
+	state->CH_Ctrl[34].bit[2] = 4;
+	state->CH_Ctrl[34].val[2] = 0;
+	state->CH_Ctrl[34].addr[3] = 92;
+	state->CH_Ctrl[34].bit[3] = 5;
+	state->CH_Ctrl[34].val[3] = 0;
+	state->CH_Ctrl[34].addr[4] = 92;
+	state->CH_Ctrl[34].bit[4] = 6;
+	state->CH_Ctrl[34].val[4] = 0;
+	state->CH_Ctrl[34].addr[5] = 92;
+	state->CH_Ctrl[34].bit[5] = 7;
+	state->CH_Ctrl[34].val[5] = 0;
+
+	state->CH_Ctrl[35].Ctrl_Num = DAC_DIN_B ;
+	state->CH_Ctrl[35].size = 6 ;
+	state->CH_Ctrl[35].addr[0] = 93;
+	state->CH_Ctrl[35].bit[0] = 2;
+	state->CH_Ctrl[35].val[0] = 0;
+	state->CH_Ctrl[35].addr[1] = 93;
+	state->CH_Ctrl[35].bit[1] = 3;
+	state->CH_Ctrl[35].val[1] = 0;
+	state->CH_Ctrl[35].addr[2] = 93;
+	state->CH_Ctrl[35].bit[2] = 4;
+	state->CH_Ctrl[35].val[2] = 0;
+	state->CH_Ctrl[35].addr[3] = 93;
+	state->CH_Ctrl[35].bit[3] = 5;
+	state->CH_Ctrl[35].val[3] = 0;
+	state->CH_Ctrl[35].addr[4] = 93;
+	state->CH_Ctrl[35].bit[4] = 6;
+	state->CH_Ctrl[35].val[4] = 0;
+	state->CH_Ctrl[35].addr[5] = 93;
+	state->CH_Ctrl[35].bit[5] = 7;
+	state->CH_Ctrl[35].val[5] = 0;
+
+#ifdef _MXL_PRODUCTION
+	state->CH_Ctrl[36].Ctrl_Num = RFSYN_EN_DIV ;
+	state->CH_Ctrl[36].size = 1 ;
+	state->CH_Ctrl[36].addr[0] = 109;
+	state->CH_Ctrl[36].bit[0] = 1;
+	state->CH_Ctrl[36].val[0] = 1;
+
+	state->CH_Ctrl[37].Ctrl_Num = RFSYN_DIVM ;
+	state->CH_Ctrl[37].size = 2 ;
+	state->CH_Ctrl[37].addr[0] = 112;
+	state->CH_Ctrl[37].bit[0] = 5;
+	state->CH_Ctrl[37].val[0] = 0;
+	state->CH_Ctrl[37].addr[1] = 112;
+	state->CH_Ctrl[37].bit[1] = 6;
+	state->CH_Ctrl[37].val[1] = 0;
+
+	state->CH_Ctrl[38].Ctrl_Num = DN_BYPASS_AGC_I2C ;
+	state->CH_Ctrl[38].size = 1 ;
+	state->CH_Ctrl[38].addr[0] = 65;
+	state->CH_Ctrl[38].bit[0] = 1;
+	state->CH_Ctrl[38].val[0] = 0;
+#endif
+
+	return 0 ;
+}
+
+static void InitTunerControls(struct dvb_frontend *fe)
+{
+	MXL5005_RegisterInit(fe);
+	MXL5005_ControlInit(fe);
+#ifdef _MXL_INTERNAL
+	MXL5005_MXLControlInit(fe);
+#endif
+}
+
+static u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
+	u8	Mode,		/* 0: Analog Mode ; 1: Digital Mode */
+	u8	IF_mode,	/* for Analog Mode, 0: zero IF; 1: low IF */
+	u32	Bandwidth,	/* filter  channel bandwidth (6, 7, 8) */
+	u32	IF_out,		/* Desired IF Out Frequency */
+	u32	Fxtal,		/* XTAL Frequency */
+	u8	AGC_Mode,	/* AGC Mode - Dual AGC: 0, Single AGC: 1 */
+	u16	TOP,		/* 0: Dual AGC; Value: take over point */
+	u16	IF_OUT_LOAD,	/* IF Out Load Resistor (200 / 300 Ohms) */
+	u8	CLOCK_OUT, 	/* 0: turn off clk out; 1: turn on clock out */
+	u8	DIV_OUT,	/* 0: Div-1; 1: Div-4 */
+	u8	CAPSELECT, 	/* 0: disable On-Chip pulling cap; 1: enable */
+	u8	EN_RSSI, 	/* 0: disable RSSI; 1: enable RSSI */
+
+	/* Modulation Type; */
+	/* 0 - Default;	1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
+	u8	Mod_Type,
+
+	/* Tracking Filter */
+	/* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
+	u8	TF_Type
+	)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+
+	state->Mode = Mode;
+	state->IF_Mode = IF_mode;
+	state->Chan_Bandwidth = Bandwidth;
+	state->IF_OUT = IF_out;
+	state->Fxtal = Fxtal;
+	state->AGC_Mode = AGC_Mode;
+	state->TOP = TOP;
+	state->IF_OUT_LOAD = IF_OUT_LOAD;
+	state->CLOCK_OUT = CLOCK_OUT;
+	state->DIV_OUT = DIV_OUT;
+	state->CAPSELECT = CAPSELECT;
+	state->EN_RSSI = EN_RSSI;
+	state->Mod_Type = Mod_Type;
+	state->TF_Type = TF_Type;
+
+	/* Initialize all the controls and registers */
+	InitTunerControls(fe);
+
+	/* Synthesizer LO frequency calculation */
+	MXL_SynthIFLO_Calc(fe);
+
+	return status;
+}
+
+static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	if (state->Mode == 1) /* Digital Mode */
+		state->IF_LO = state->IF_OUT;
+	else /* Analog Mode */ {
+		if (state->IF_Mode == 0) /* Analog Zero IF mode */
+			state->IF_LO = state->IF_OUT + 400000;
+		else /* Analog Low IF mode */
+			state->IF_LO = state->IF_OUT + state->Chan_Bandwidth/2;
+	}
+}
+
+static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+
+	if (state->Mode == 1) /* Digital Mode */ {
+			/* remove 20.48MHz setting for 2.6.10 */
+			state->RF_LO = state->RF_IN;
+			/* change for 2.6.6 */
+			state->TG_LO = state->RF_IN - 750000;
+	} else /* Analog Mode */ {
+		if (state->IF_Mode == 0) /* Analog Zero IF mode */ {
+			state->RF_LO = state->RF_IN - 400000;
+			state->TG_LO = state->RF_IN - 1750000;
+		} else /* Analog Low IF mode */ {
+			state->RF_LO = state->RF_IN - state->Chan_Bandwidth/2;
+			state->TG_LO = state->RF_IN -
+				state->Chan_Bandwidth + 500000;
+		}
+	}
+}
+
+static u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
+{
+	u16 status = 0;
+
+	status += MXL_ControlWrite(fe, OVERRIDE_1, 1);
+	status += MXL_ControlWrite(fe, OVERRIDE_2, 1);
+	status += MXL_ControlWrite(fe, OVERRIDE_3, 1);
+	status += MXL_ControlWrite(fe, OVERRIDE_4, 1);
+
+	return status;
+}
+
+static u16 MXL_BlockInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+
+	status += MXL_OverwriteICDefault(fe);
+
+	/* Downconverter Control Dig Ana */
+	status += MXL_ControlWrite(fe, DN_IQTN_AMP_CUT, state->Mode ? 1 : 0);
+
+	/* Filter Control  Dig  Ana */
+	status += MXL_ControlWrite(fe, BB_MODE, state->Mode ? 0 : 1);
+	status += MXL_ControlWrite(fe, BB_BUF, state->Mode ? 3 : 2);
+	status += MXL_ControlWrite(fe, BB_BUF_OA, state->Mode ? 1 : 0);
+	status += MXL_ControlWrite(fe, BB_IQSWAP, state->Mode ? 0 : 1);
+	status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 0);
+
+	/* Initialize Low-Pass Filter */
+	if (state->Mode) { /* Digital Mode */
+		switch (state->Chan_Bandwidth) {
+		case 8000000:
+			status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 0);
+			break;
+		case 7000000:
+			status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2);
+			break;
+		case 6000000:
+			status += MXL_ControlWrite(fe,
+					BB_DLPF_BANDSEL, 3);
+			break;
+		}
+	} else { /* Analog Mode */
+		switch (state->Chan_Bandwidth) {
+		case 8000000:	/* Low Zero */
+			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+					(state->IF_Mode ? 0 : 3));
+			break;
+		case 7000000:
+			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+					(state->IF_Mode ? 1 : 4));
+			break;
+		case 6000000:
+			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+					(state->IF_Mode ? 2 : 5));
+			break;
+		}
+	}
+
+	/* Charge Pump Control Dig  Ana */
+	status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, state->Mode ? 5 : 8);
+	status += MXL_ControlWrite(fe,
+		RFSYN_EN_CHP_HIGAIN, state->Mode ? 1 : 1);
+	status += MXL_ControlWrite(fe, EN_CHP_LIN_B, state->Mode ? 0 : 0);
+
+	/* AGC TOP Control */
+	if (state->AGC_Mode == 0) /* Dual AGC */ {
+		status += MXL_ControlWrite(fe, AGC_IF, 15);
+		status += MXL_ControlWrite(fe, AGC_RF, 15);
+	} else /*  Single AGC Mode Dig  Ana */
+		status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12);
+
+	if (state->TOP == 55) /* TOP == 5.5 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x0);
+
+	if (state->TOP == 72) /* TOP == 7.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x1);
+
+	if (state->TOP == 92) /* TOP == 9.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x2);
+
+	if (state->TOP == 110) /* TOP == 11.0 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x3);
+
+	if (state->TOP == 129) /* TOP == 12.9 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x4);
+
+	if (state->TOP == 147) /* TOP == 14.7 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x5);
+
+	if (state->TOP == 168) /* TOP == 16.8 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x6);
+
+	if (state->TOP == 194) /* TOP == 19.4 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x7);
+
+	if (state->TOP == 212) /* TOP == 21.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x9);
+
+	if (state->TOP == 232) /* TOP == 23.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xA);
+
+	if (state->TOP == 252) /* TOP == 25.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xB);
+
+	if (state->TOP == 271) /* TOP == 27.1 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xC);
+
+	if (state->TOP == 292) /* TOP == 29.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xD);
+
+	if (state->TOP == 317) /* TOP == 31.7 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xE);
+
+	if (state->TOP == 349) /* TOP == 34.9 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xF);
+
+	/* IF Synthesizer Control */
+	status += MXL_IFSynthInit(fe);
+
+	/* IF UpConverter Control */
+	if (state->IF_OUT_LOAD == 200) {
+		status += MXL_ControlWrite(fe, DRV_RES_SEL, 6);
+		status += MXL_ControlWrite(fe, I_DRIVER, 2);
+	}
+	if (state->IF_OUT_LOAD == 300) {
+		status += MXL_ControlWrite(fe, DRV_RES_SEL, 4);
+		status += MXL_ControlWrite(fe, I_DRIVER, 1);
+	}
+
+	/* Anti-Alias Filtering Control
+	 * initialise Anti-Aliasing Filter
+	 */
+	if (state->Mode) { /* Digital Mode */
+		if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 6280000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 1);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+		}
+		if ((state->IF_OUT == 36125000UL) ||
+			(state->IF_OUT == 36150000UL)) {
+			status += MXL_ControlWrite(fe, EN_AAF, 1);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
+		}
+		if (state->IF_OUT > 36150000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 0);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
+		}
+	} else { /* Analog Mode */
+		if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 5000000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 1);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+		}
+		if (state->IF_OUT > 5000000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 0);
+			status += MXL_ControlWrite(fe, EN_3P, 0);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 0);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+		}
+	}
+
+	/* Demod Clock Out */
+	if (state->CLOCK_OUT)
+		status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 1);
+	else
+		status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 0);
+
+	if (state->DIV_OUT == 1)
+		status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 1);
+	if (state->DIV_OUT == 0)
+		status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 0);
+
+	/* Crystal Control */
+	if (state->CAPSELECT)
+		status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 1);
+	else
+		status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 0);
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
+		status += MXL_ControlWrite(fe, IF_SEL_DBL, 1);
+	if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
+		status += MXL_ControlWrite(fe, IF_SEL_DBL, 0);
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
+		status += MXL_ControlWrite(fe, RFSYN_R_DIV, 3);
+	if (state->Fxtal > 22000000UL && state->Fxtal <= 32000000UL)
+		status += MXL_ControlWrite(fe, RFSYN_R_DIV, 0);
+
+	/* Misc Controls */
+	if (state->Mode == 0 && state->IF_Mode == 1) /* Analog LowIF mode */
+		status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 0);
+	else
+		status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 1);
+
+	/* status += MXL_ControlRead(fe, IF_DIVVAL, &IF_DIVVAL_Val); */
+
+	/* Set TG_R_DIV */
+	status += MXL_ControlWrite(fe, TG_R_DIV,
+		MXL_Ceiling(state->Fxtal, 1000000));
+
+	/* Apply Default value to BB_INITSTATE_DLPF_TUNE */
+
+	/* RSSI Control */
+	if (state->EN_RSSI) {
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+		/* TOP point */
+		status += MXL_ControlWrite(fe, RFA_FLR, 0);
+		status += MXL_ControlWrite(fe, RFA_CEIL, 12);
+	}
+
+	/* Modulation type bit settings
+	 * Override the control values preset
+	 */
+	if (state->Mod_Type == MXL_DVBT) /* DVB-T Mode */ {
+		state->AGC_Mode = 1; /* Single AGC Mode */
+
+		/* Enable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+		/* TOP point */
+		status += MXL_ControlWrite(fe, RFA_FLR, 2);
+		status += MXL_ControlWrite(fe, RFA_CEIL, 13);
+		if (state->IF_OUT <= 6280000UL)	/* Low IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+		else /* High IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+
+	}
+	if (state->Mod_Type == MXL_ATSC) /* ATSC Mode */ {
+		state->AGC_Mode = 1;	/* Single AGC Mode */
+
+		/* Enable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 4);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+		/* TOP point */
+		status += MXL_ControlWrite(fe, RFA_FLR, 2);
+		status += MXL_ControlWrite(fe, RFA_CEIL, 13);
+		status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 1);
+		/* Low Zero */
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
+
+		if (state->IF_OUT <= 6280000UL)	/* Low IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+		else /* High IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+	}
+	if (state->Mod_Type == MXL_QAM) /* QAM Mode */ {
+		state->Mode = MXL_DIGITAL_MODE;
+
+		/* state->AGC_Mode = 1; */ /* Single AGC Mode */
+
+		/* Disable RSSI */	/* change here for v2.6.5 */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+		/* change here for v2.6.5 */
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+
+		if (state->IF_OUT <= 6280000UL)	/* Low IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+		else /* High IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
+
+	}
+	if (state->Mod_Type == MXL_ANALOG_CABLE) {
+		/* Analog Cable Mode */
+		/* state->Mode = MXL_DIGITAL_MODE; */
+
+		state->AGC_Mode = 1; /* Single AGC Mode */
+
+		/* Disable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+		/* change for 2.6.3 */
+		status += MXL_ControlWrite(fe, AGC_IF, 1);
+		status += MXL_ControlWrite(fe, AGC_RF, 15);
+		status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+	}
+
+	if (state->Mod_Type == MXL_ANALOG_OTA) {
+		/* Analog OTA Terrestrial mode add for 2.6.7 */
+		/* state->Mode = MXL_ANALOG_MODE; */
+
+		/* Enable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+		status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+	}
+
+	/* RSSI disable */
+	if (state->EN_RSSI == 0) {
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+	}
+
+	return status;
+}
+
+static u16 MXL_IFSynthInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0 ;
+	u32	Fref = 0 ;
+	u32	Kdbl, intModVal ;
+	u32	fracModVal ;
+	Kdbl = 2 ;
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
+		Kdbl = 2 ;
+	if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
+		Kdbl = 1 ;
+
+	/* IF Synthesizer Control */
+	if (state->Mode == 0 && state->IF_Mode == 1) /* Analog Low IF mode */ {
+		if (state->IF_LO == 41000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 328000000UL ;
+		}
+		if (state->IF_LO == 47000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 376000000UL ;
+		}
+		if (state->IF_LO == 54000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 324000000UL ;
+		}
+		if (state->IF_LO == 60000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 39250000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 314000000UL ;
+		}
+		if (state->IF_LO == 39650000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 317200000UL ;
+		}
+		if (state->IF_LO == 40150000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 321200000UL ;
+		}
+		if (state->IF_LO == 40650000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 325200000UL ;
+		}
+	}
+
+	if (state->Mode || (state->Mode == 0 && state->IF_Mode == 0)) {
+		if (state->IF_LO == 57000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 342000000UL ;
+		}
+		if (state->IF_LO == 44000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352000000UL ;
+		}
+		if (state->IF_LO == 43750000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 350000000UL ;
+		}
+		if (state->IF_LO == 36650000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 366500000UL ;
+		}
+		if (state->IF_LO == 36150000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 361500000UL ;
+		}
+		if (state->IF_LO == 36000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 35250000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352500000UL ;
+		}
+		if (state->IF_LO == 34750000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 347500000UL ;
+		}
+		if (state->IF_LO == 6280000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 376800000UL ;
+		}
+		if (state->IF_LO == 5000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 4500000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 4570000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 365600000UL ;
+		}
+		if (state->IF_LO == 4000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x05);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 57400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 344400000UL ;
+		}
+		if (state->IF_LO == 44400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 355200000UL ;
+		}
+		if (state->IF_LO == 44150000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 353200000UL ;
+		}
+		if (state->IF_LO == 37050000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 370500000UL ;
+		}
+		if (state->IF_LO == 36550000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 365500000UL ;
+		}
+		if (state->IF_LO == 36125000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 361250000UL ;
+		}
+		if (state->IF_LO == 6000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 5400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 324000000UL ;
+		}
+		if (state->IF_LO == 5380000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 322800000UL ;
+		}
+		if (state->IF_LO == 5200000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 374400000UL ;
+		}
+		if (state->IF_LO == 4900000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352800000UL ;
+		}
+		if (state->IF_LO == 4400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352000000UL ;
+		}
+		if (state->IF_LO == 4063000UL)  /* add for 2.6.8 */ {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x05);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 365670000UL ;
+		}
+	}
+	/* CHCAL_INT_MOD_IF */
+	/* CHCAL_FRAC_MOD_IF */
+	intModVal = Fref / (state->Fxtal * Kdbl/2);
+	status += MXL_ControlWrite(fe, CHCAL_INT_MOD_IF, intModVal);
+
+	fracModVal = (2<<15)*(Fref/1000 - (state->Fxtal/1000 * Kdbl/2) *
+		intModVal);
+
+	fracModVal = fracModVal / ((state->Fxtal * Kdbl/2)/1000);
+	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_IF, fracModVal);
+
+	return status ;
+}
+
+static u32 MXL_GetXtalInt(u32 Xtal_Freq)
+{
+	if ((Xtal_Freq % 1000000) == 0)
+		return (Xtal_Freq / 10000);
+	else
+		return (((Xtal_Freq / 1000000) + 1)*100);
+}
+
+static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+	u32 divider_val, E3, E4, E5, E5A;
+	u32 Fmax, Fmin, FmaxBin, FminBin;
+	u32 Kdbl_RF = 2;
+	u32 tg_divval;
+	u32 tg_lo;
+	u32 Xtal_Int;
+
+	u32 Fref_TG;
+	u32 Fvco;
+
+	Xtal_Int = MXL_GetXtalInt(state->Fxtal);
+
+	state->RF_IN = RF_Freq;
+
+	MXL_SynthRFTGLO_Calc(fe);
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
+		Kdbl_RF = 2;
+	if (state->Fxtal > 22000000 && state->Fxtal <= 32000000)
+		Kdbl_RF = 1;
+
+	/* Downconverter Controls
+	 * Look-Up Table Implementation for:
+	 *	DN_POLY
+	 *	DN_RFGAIN
+	 *	DN_CAP_RFLPF
+	 *	DN_EN_VHFUHFBAR
+	 *	DN_GAIN_ADJUST
+	 *  Change the boundary reference from RF_IN to RF_LO
+	 */
+	if (state->RF_LO < 40000000UL)
+		return -1;
+
+	if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              2);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         423);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       1);
+	}
+	if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         222);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       1);
+	}
+	if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         147);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       2);
+	}
+	if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         9);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       2);
+	}
+	if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
+	}
+	if (state->RF_LO > 300000000UL && state->RF_LO <= 650000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            1);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      0);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
+	}
+	if (state->RF_LO > 650000000UL && state->RF_LO <= 900000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            2);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      0);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
+	}
+	if (state->RF_LO > 900000000UL)
+		return -1;
+
+	/*	DN_IQTNBUF_AMP */
+	/*	DN_IQTNGNBFBIAS_BST */
+	if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 300000000UL && state->RF_LO <= 400000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 400000000UL && state->RF_LO <= 450000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 450000000UL && state->RF_LO <= 500000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 500000000UL && state->RF_LO <= 550000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 550000000UL && state->RF_LO <= 600000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 600000000UL && state->RF_LO <= 650000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 650000000UL && state->RF_LO <= 700000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 700000000UL && state->RF_LO <= 750000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 750000000UL && state->RF_LO <= 800000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 800000000UL && state->RF_LO <= 850000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       10);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  1);
+	}
+	if (state->RF_LO > 850000000UL && state->RF_LO <= 900000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       10);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  1);
+	}
+
+	/*
+	 * Set RF Synth and LO Path Control
+	 *
+	 * Look-Up table implementation for:
+	 *	RFSYN_EN_OUTMUX
+	 *	RFSYN_SEL_VCO_OUT
+	 *	RFSYN_SEL_VCO_HI
+	 *  RFSYN_SEL_DIVM
+	 *	RFSYN_RF_DIV_BIAS
+	 *	DN_SEL_FREQ
+	 *
+	 * Set divider_val, Fmax, Fmix to use in Equations
+	 */
+	FminBin = 28000000UL ;
+	FmaxBin = 42500000UL ;
+	if (state->RF_LO >= 40000000UL && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 64 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 42500000UL ;
+	FmaxBin = 56000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 64 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 56000000UL ;
+	FmaxBin = 85000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 32 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 85000000UL ;
+	FmaxBin = 112000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 32 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 112000000UL ;
+	FmaxBin = 170000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         2);
+		divider_val = 16 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 170000000UL ;
+	FmaxBin = 225000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         2);
+		divider_val = 16 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 225000000UL ;
+	FmaxBin = 300000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         4);
+		divider_val = 8 ;
+		Fmax = 340000000UL ;
+		Fmin = FminBin ;
+	}
+	FminBin = 300000000UL ;
+	FmaxBin = 340000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 8 ;
+		Fmax = FmaxBin ;
+		Fmin = 225000000UL ;
+	}
+	FminBin = 340000000UL ;
+	FmaxBin = 450000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   2);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 8 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 450000000UL ;
+	FmaxBin = 680000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 4 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 680000000UL ;
+	FmaxBin = 900000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 4 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+
+	/*	CHCAL_INT_MOD_RF
+	 *	CHCAL_FRAC_MOD_RF
+	 *	RFSYN_LPF_R
+	 *	CHCAL_EN_INT_RF
+	 */
+	/* Equation E3 RFSYN_VCO_BIAS */
+	E3 = (((Fmax-state->RF_LO)/1000)*32)/((Fmax-Fmin)/1000) + 8 ;
+	status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, E3);
+
+	/* Equation E4 CHCAL_INT_MOD_RF */
+	E4 = (state->RF_LO*divider_val/1000)/(2*state->Fxtal*Kdbl_RF/1000);
+	MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, E4);
+
+	/* Equation E5 CHCAL_FRAC_MOD_RF CHCAL_EN_INT_RF */
+	E5 = ((2<<17)*(state->RF_LO/10000*divider_val -
+		(E4*(2*state->Fxtal*Kdbl_RF)/10000))) /
+		(2*state->Fxtal*Kdbl_RF/10000);
+
+	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
+
+	/* Equation E5A RFSYN_LPF_R */
+	E5A = (((Fmax - state->RF_LO)/1000)*4/((Fmax-Fmin)/1000)) + 1 ;
+	status += MXL_ControlWrite(fe, RFSYN_LPF_R, E5A);
+
+	/* Euqation E5B CHCAL_EN_INIT_RF */
+	status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, ((E5 == 0) ? 1 : 0));
+	/*if (E5 == 0)
+	 *	status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, 1);
+	 *else
+	 *	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
+	 */
+
+	/*
+	 * Set TG Synth
+	 *
+	 * Look-Up table implementation for:
+	 *	TG_LO_DIVVAL
+	 *	TG_LO_SELVAL
+	 *
+	 * Set divider_val, Fmax, Fmix to use in Equations
+	 */
+	if (state->TG_LO < 33000000UL)
+		return -1;
+
+	FminBin = 33000000UL ;
+	FmaxBin = 50000000UL ;
+	if (state->TG_LO >= FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x6);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x0);
+		divider_val = 36 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 50000000UL ;
+	FmaxBin = 67000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x1);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x0);
+		divider_val = 24 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 67000000UL ;
+	FmaxBin = 100000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0xC);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
+		divider_val = 18 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 100000000UL ;
+	FmaxBin = 150000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
+		divider_val = 12 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 150000000UL ;
+	FmaxBin = 200000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
+		divider_val = 8 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 200000000UL ;
+	FmaxBin = 300000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x3);
+		divider_val = 6 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 300000000UL ;
+	FmaxBin = 400000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x3);
+		divider_val = 4 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 400000000UL ;
+	FmaxBin = 600000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x7);
+		divider_val = 3 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 600000000UL ;
+	FmaxBin = 900000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x7);
+		divider_val = 2 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+
+	/* TG_DIV_VAL */
+	tg_divval = (state->TG_LO*divider_val/100000) *
+		(MXL_Ceiling(state->Fxtal, 1000000) * 100) /
+		(state->Fxtal/1000);
+
+	status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval);
+
+	if (state->TG_LO > 600000000UL)
+		status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval + 1);
+
+	Fmax = 1800000000UL ;
+	Fmin = 1200000000UL ;
+
+	/* prevent overflow of 32 bit unsigned integer, use
+	 * following equation. Edit for v2.6.4
+	 */
+	/* Fref_TF = Fref_TG * 1000 */
+	Fref_TG = (state->Fxtal/1000) / MXL_Ceiling(state->Fxtal, 1000000);
+
+	/* Fvco = Fvco/10 */
+	Fvco = (state->TG_LO/10000) * divider_val * Fref_TG;
+
+	tg_lo = (((Fmax/10 - Fvco)/100)*32) / ((Fmax-Fmin)/1000)+8;
+
+	/* below equation is same as above but much harder to debug.
+	 * tg_lo = ( ((Fmax/10000 * Xtal_Int)/100) -
+	 * ((state->TG_LO/10000)*divider_val *
+	 * (state->Fxtal/10000)/100) )*32/((Fmax-Fmin)/10000 *
+	 * Xtal_Int/100) + 8;
+	 */
+
+	status += MXL_ControlWrite(fe, TG_VCO_BIAS , tg_lo);
+
+	/* add for 2.6.5 Special setting for QAM */
+	if (state->Mod_Type == MXL_QAM) {
+		if (state->RF_IN < 680000000)
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+		else
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
+	}
+
+	/* Off Chip Tracking Filter Control */
+	if (state->TF_Type == MXL_TF_OFF) {
+		/* Tracking Filter Off State; turn off all the banks */
+		status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+		status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+		status += MXL_SetGPIO(fe, 3, 1); /* Bank1 Off */
+		status += MXL_SetGPIO(fe, 1, 1); /* Bank2 Off */
+		status += MXL_SetGPIO(fe, 4, 1); /* Bank3 Off */
+	}
+
+	if (state->TF_Type == MXL_TF_C) /* Tracking Filter type C */ {
+		status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 29);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 16);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 7);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_C_H) {
+
+		/* Tracking Filter type C-H for Hauppauge only */
+		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_D) { /* Tracking Filter type D */
+
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_D_L) {
+
+		/* Tracking Filter type D-L for Lumanate ONLY change 2.6.3 */
+		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+		/* if UHF and terrestrial => Turn off Tracking Filter */
+		if (state->RF_IN >= 471000000 &&
+			(state->RF_IN - 471000000)%6000000 != 0) {
+			/* Turn off all the banks */
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, AGC_IF, 10);
+		} else {
+			/* if VHF or cable => Turn on Tracking Filter */
+			if (state->RF_IN >= 43000000 &&
+				state->RF_IN < 140000000) {
+
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 0);
+			}
+			if (state->RF_IN >= 140000000 &&
+				state->RF_IN < 240000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 0);
+			}
+			if (state->RF_IN >= 240000000 &&
+				state->RF_IN < 340000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 0);
+			}
+			if (state->RF_IN >= 340000000 &&
+				state->RF_IN < 430000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 430000000 &&
+				state->RF_IN < 470000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 470000000 &&
+				state->RF_IN < 570000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 570000000 &&
+				state->RF_IN < 620000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 620000000 &&
+				state->RF_IN < 760000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 760000000 &&
+				state->RF_IN <= 900000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_E) /* Tracking Filter type E */ {
+
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_F) {
+
+		/* Tracking Filter type F */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 160000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 160000000 && state->RF_IN < 210000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 210000000 && state->RF_IN < 300000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 300000000 && state->RF_IN < 390000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 390000000 && state->RF_IN < 515000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 515000000 && state->RF_IN < 650000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 650000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_E_2) {
+
+		/* Tracking Filter type E_2 */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_G) {
+
+		/* Tracking Filter type G add for v2.6.8 */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 50000000 && state->RF_IN < 190000000) {
+
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 190000000 && state->RF_IN < 280000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 280000000 && state->RF_IN < 350000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 400000000 && state->RF_IN < 470000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 640000000 && state->RF_IN < 820000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 820000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_E_NA) {
+
+		/* Tracking Filter type E-NA for Empia ONLY change for 2.6.8 */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		/* if UHF and terrestrial=> Turn off Tracking Filter */
+		if (state->RF_IN >= 471000000 &&
+			(state->RF_IN - 471000000)%6000000 != 0) {
+
+			/* Turn off all the banks */
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+
+			/* 2.6.12 Turn on RSSI */
+			status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+			status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+			status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+			status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+			/* RSSI reference point */
+			status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+			status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+			status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+
+			/* following parameter is from analog OTA mode,
+			 * can be change to seek better performance */
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+		} else {
+		/* if VHF or Cable =>  Turn on Tracking Filter */
+
+		/* 2.6.12 Turn off RSSI */
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+
+		/* change back from above condition */
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
+
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		}
+	}
+	return status ;
+}
+
+static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
+{
+	u16 status = 0;
+
+	if (GPIO_Num == 1)
+		status += MXL_ControlWrite(fe, GPIO_1B, GPIO_Val ? 0 : 1);
+
+	/* GPIO2 is not available */
+
+	if (GPIO_Num == 3) {
+		if (GPIO_Val == 1) {
+			status += MXL_ControlWrite(fe, GPIO_3, 0);
+			status += MXL_ControlWrite(fe, GPIO_3B, 0);
+		}
+		if (GPIO_Val == 0) {
+			status += MXL_ControlWrite(fe, GPIO_3, 1);
+			status += MXL_ControlWrite(fe, GPIO_3B, 1);
+		}
+		if (GPIO_Val == 3) { /* tri-state */
+			status += MXL_ControlWrite(fe, GPIO_3, 0);
+			status += MXL_ControlWrite(fe, GPIO_3B, 1);
+		}
+	}
+	if (GPIO_Num == 4) {
+		if (GPIO_Val == 1) {
+			status += MXL_ControlWrite(fe, GPIO_4, 0);
+			status += MXL_ControlWrite(fe, GPIO_4B, 0);
+		}
+		if (GPIO_Val == 0) {
+			status += MXL_ControlWrite(fe, GPIO_4, 1);
+			status += MXL_ControlWrite(fe, GPIO_4B, 1);
+		}
+		if (GPIO_Val == 3) { /* tri-state */
+			status += MXL_ControlWrite(fe, GPIO_4, 0);
+			status += MXL_ControlWrite(fe, GPIO_4B, 1);
+		}
+	}
+
+	return status;
+}
+
+static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
+{
+	u16 status = 0;
+
+	/* Will write ALL Matching Control Name */
+	/* Write Matching INIT Control */
+	status += MXL_ControlWrite_Group(fe, ControlNum, value, 1);
+	/* Write Matching CH Control */
+	status += MXL_ControlWrite_Group(fe, ControlNum, value, 2);
+#ifdef _MXL_INTERNAL
+	/* Write Matching MXL Control */
+	status += MXL_ControlWrite_Group(fe, ControlNum, value, 3);
+#endif
+	return status;
+}
+
+static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
+	u32 value, u16 controlGroup)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 i, j, k;
+	u32 highLimit;
+	u32 ctrlVal;
+
+	if (controlGroup == 1) /* Initial Control */ {
+
+		for (i = 0; i < state->Init_Ctrl_Num; i++) {
+
+			if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
+
+				highLimit = 1 << state->Init_Ctrl[i].size;
+				if (value < highLimit) {
+					for (j = 0; j < state->Init_Ctrl[i].size; j++) {
+						state->Init_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+						MXL_RegWriteBit(fe, (u8)(state->Init_Ctrl[i].addr[j]),
+							(u8)(state->Init_Ctrl[i].bit[j]),
+							(u8)((value>>j) & 0x01));
+					}
+					ctrlVal = 0;
+					for (k = 0; k < state->Init_Ctrl[i].size; k++)
+						ctrlVal += state->Init_Ctrl[i].val[k] * (1 << k);
+				} else
+					return -1;
+			}
+		}
+	}
+	if (controlGroup == 2) /* Chan change Control */ {
+
+		for (i = 0; i < state->CH_Ctrl_Num; i++) {
+
+			if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
+
+				highLimit = 1 << state->CH_Ctrl[i].size;
+				if (value < highLimit) {
+					for (j = 0; j < state->CH_Ctrl[i].size; j++) {
+						state->CH_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+						MXL_RegWriteBit(fe, (u8)(state->CH_Ctrl[i].addr[j]),
+							(u8)(state->CH_Ctrl[i].bit[j]),
+							(u8)((value>>j) & 0x01));
+					}
+					ctrlVal = 0;
+					for (k = 0; k < state->CH_Ctrl[i].size; k++)
+						ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
+				} else
+					return -1;
+			}
+		}
+	}
+#ifdef _MXL_INTERNAL
+	if (controlGroup == 3) /* Maxlinear Control */ {
+
+		for (i = 0; i < state->MXL_Ctrl_Num; i++) {
+
+			if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
+
+				highLimit = (1 << state->MXL_Ctrl[i].size);
+				if (value < highLimit) {
+					for (j = 0; j < state->MXL_Ctrl[i].size; j++) {
+						state->MXL_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+						MXL_RegWriteBit(fe, (u8)(state->MXL_Ctrl[i].addr[j]),
+							(u8)(state->MXL_Ctrl[i].bit[j]),
+							(u8)((value>>j) & 0x01));
+					}
+					ctrlVal = 0;
+					for (k = 0; k < state->MXL_Ctrl[i].size; k++)
+						ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k);
+				} else
+					return -1;
+			}
+		}
+	}
+#endif
+	return 0 ; /* successful return */
+}
+
+static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	int i ;
+
+	for (i = 0; i < 104; i++) {
+		if (RegNum == state->TunerRegs[i].Reg_Num) {
+			*RegVal = (u8)(state->TunerRegs[i].Reg_Val);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u32 ctrlVal ;
+	u16 i, k ;
+
+	for (i = 0; i < state->Init_Ctrl_Num ; i++) {
+
+		if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
+
+			ctrlVal = 0;
+			for (k = 0; k < state->Init_Ctrl[i].size; k++)
+				ctrlVal += state->Init_Ctrl[i].val[k] * (1<<k);
+			*value = ctrlVal;
+			return 0;
+		}
+	}
+
+	for (i = 0; i < state->CH_Ctrl_Num ; i++) {
+
+		if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
+
+			ctrlVal = 0;
+			for (k = 0; k < state->CH_Ctrl[i].size; k++)
+				ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
+			*value = ctrlVal;
+			return 0;
+
+		}
+	}
+
+#ifdef _MXL_INTERNAL
+	for (i = 0; i < state->MXL_Ctrl_Num ; i++) {
+
+		if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
+
+			ctrlVal = 0;
+			for (k = 0; k < state->MXL_Ctrl[i].size; k++)
+				ctrlVal += state->MXL_Ctrl[i].val[k] * (1<<k);
+			*value = ctrlVal;
+			return 0;
+
+		}
+	}
+#endif
+	return 1;
+}
+
+static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
+	u8 bitVal)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	int i ;
+
+	const u8 AND_MAP[8] = {
+		0xFE, 0xFD, 0xFB, 0xF7,
+		0xEF, 0xDF, 0xBF, 0x7F } ;
+
+	const u8 OR_MAP[8] = {
+		0x01, 0x02, 0x04, 0x08,
+		0x10, 0x20, 0x40, 0x80 } ;
+
+	for (i = 0; i < state->TunerRegs_Num; i++) {
+		if (state->TunerRegs[i].Reg_Num == address) {
+			if (bitVal)
+				state->TunerRegs[i].Reg_Val |= OR_MAP[bit];
+			else
+				state->TunerRegs[i].Reg_Val &= AND_MAP[bit];
+			break ;
+		}
+	}
+}
+
+static u32 MXL_Ceiling(u32 value, u32 resolution)
+{
+	return (value/resolution + (value % resolution > 0 ? 1 : 0));
+}
+
+/* Retrieve the Initialzation Registers */
+static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count)
+{
+	u16 status = 0;
+	int i ;
+
+	u8 RegAddr[] = {
+		11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73,
+		76, 77, 91, 134, 135, 137, 147,
+		156, 166, 167, 168, 25 };
+
+	*count = sizeof(RegAddr) / sizeof(u8);
+
+	status += MXL_BlockInit(fe);
+
+	for (i = 0 ; i < *count; i++) {
+		RegNum[i] = RegAddr[i];
+		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+	}
+
+	return status;
+}
+
+static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
+	int *count)
+{
+	u16 status = 0;
+	int i ;
+
+/* add 77, 166, 167, 168 register for 2.6.12 */
+#ifdef _MXL_PRODUCTION
+	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
+	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+#else
+	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
+	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+	/*
+	u8 RegAddr[171];
+	for (i = 0; i <= 170; i++)
+		RegAddr[i] = i;
+	*/
+#endif
+
+	*count = sizeof(RegAddr) / sizeof(u8);
+
+	for (i = 0 ; i < *count; i++) {
+		RegNum[i] = RegAddr[i];
+		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+	}
+
+	return status;
+}
+
+static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count)
+{
+	u16 status = 0;
+	int i;
+
+	u8 RegAddr[] = {43, 136};
+
+	*count = sizeof(RegAddr) / sizeof(u8);
+
+	for (i = 0; i < *count; i++) {
+		RegNum[i] = RegAddr[i];
+		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+	}
+
+	return status;
+}
+
+static u16 MXL_GetMasterControl(u8 *MasterReg, int state)
+{
+	if (state == 1) /* Load_Start */
+		*MasterReg = 0xF3;
+	if (state == 2) /* Power_Down */
+		*MasterReg = 0x41;
+	if (state == 3) /* Synth_Reset */
+		*MasterReg = 0xB1;
+	if (state == 4) /* Seq_Off */
+		*MasterReg = 0xF1;
+
+	return 0;
+}
+
+#ifdef _MXL_PRODUCTION
+static u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0 ;
+
+	if (VCO_Range == 1) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 180224);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 222822);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 229376);
+		}
+	}
+
+	if (VCO_Range == 2) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 16384);
+		}
+	}
+
+	if (VCO_Range == 3) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 173670);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 173670);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 245760);
+		}
+	}
+
+	if (VCO_Range == 4) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 212992);
+		}
+	}
+
+	return status;
+}
+
+static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+
+	if (Hystersis == 1)
+		status += MXL_ControlWrite(fe, DN_BYPASS_AGC_I2C, 1);
+
+	return status;
+}
+#endif
+/* End: Reference driver code found in the Realtek driver that
+ * is copyright MaxLinear */
+
+/* ----------------------------------------------------------------
+ * Begin: Everything after here is new code to adapt the
+ * proprietary Realtek driver into a Linux API tuner.
+ * Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+ */
+static int mxl5005s_reset(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	int ret = 0;
+
+	u8 buf[2] = { 0xff, 0x00 };
+	struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
+			       .buf = buf, .len = 2 };
+
+	dprintk(2, "%s()\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		printk(KERN_WARNING "mxl5005s I2C reset failed\n");
+		ret = -EREMOTEIO;
+	}
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+/* Write a single byte to a single reg, latch the value if required by
+ * following the transaction with the latch byte.
+ */
+static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE };
+	struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
+			       .buf = buf, .len = 3 };
+
+	if (latch == 0)
+		msg.len = 2;
+
+	dprintk(2, "%s(0x%x, 0x%x, 0x%x)\n", __func__, reg, val, msg.addr);
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		printk(KERN_WARNING "mxl5005s I2C write failed\n");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
+	u8 *datatable, u8 len)
+{
+	int ret = 0, i;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	for (i = 0 ; i < len-1; i++) {
+		ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0);
+		if (ret < 0)
+			break;
+	}
+
+	ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+static int mxl5005s_init(struct dvb_frontend *fe)
+{
+	dprintk(1, "%s()\n", __func__);
+	return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
+}
+
+static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+
+	u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	int TableLen;
+
+	dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth);
+
+	mxl5005s_reset(fe);
+
+	/* Tuner initialization stage 0 */
+	MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
+	AddrTable[0] = MASTER_CONTROL_ADDR;
+	ByteTable[0] |= state->config->AgcMasterByte;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
+
+	mxl5005s_AssignTunerMode(fe, mod_type, bandwidth);
+
+	/* Tuner initialization stage 1 */
+	MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen);
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+	return 0;
+}
+
+static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	struct mxl5005s_config *c = state->config;
+
+	InitTunerControls(fe);
+
+	/* Set MxL5005S parameters. */
+	MXL5005_TunerConfig(
+		fe,
+		c->mod_mode,
+		c->if_mode,
+		bandwidth,
+		c->if_freq,
+		c->xtal_freq,
+		c->agc_mode,
+		c->top,
+		c->output_load,
+		c->clock_out,
+		c->div_out,
+		c->cap_select,
+		c->rssi_enable,
+		mod_type,
+		c->tracking_filter);
+
+	return 0;
+}
+
+static int mxl5005s_set_params(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *params)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u32 req_mode, req_bw = 0;
+	int ret;
+
+	dprintk(1, "%s()\n", __func__);
+
+	if (fe->ops.info.type == FE_ATSC) {
+		switch (params->u.vsb.modulation) {
+		case VSB_8:
+			req_mode = MXL_ATSC; break;
+		default:
+		case QAM_64:
+		case QAM_256:
+		case QAM_AUTO:
+			req_mode = MXL_QAM; break;
+		}
+	} else
+		req_mode = MXL_DVBT;
+
+	/* Change tuner for new modulation type if reqd */
+	if (req_mode != state->current_mode) {
+		switch (req_mode) {
+		case VSB_8:
+		case QAM_64:
+		case QAM_256:
+		case QAM_AUTO:
+			req_bw  = MXL5005S_BANDWIDTH_6MHZ;
+			break;
+		default:
+			/* Assume DVB-T */
+			switch (params->u.ofdm.bandwidth) {
+			case BANDWIDTH_6_MHZ:
+				req_bw  = MXL5005S_BANDWIDTH_6MHZ;
+				break;
+			case BANDWIDTH_7_MHZ:
+				req_bw  = MXL5005S_BANDWIDTH_7MHZ;
+				break;
+			case BANDWIDTH_AUTO:
+			case BANDWIDTH_8_MHZ:
+				req_bw  = MXL5005S_BANDWIDTH_8MHZ;
+				break;
+			}
+		}
+
+		state->current_mode = req_mode;
+		ret = mxl5005s_reconfigure(fe, req_mode, req_bw);
+
+	} else
+		ret = 0;
+
+	if (ret == 0) {
+		dprintk(1, "%s() freq=%d\n", __func__, params->frequency);
+		ret = mxl5005s_SetRfFreqHz(fe, params->frequency);
+	}
+
+	return ret;
+}
+
+static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	dprintk(1, "%s()\n", __func__);
+
+	*frequency = state->RF_IN;
+
+	return 0;
+}
+
+static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	dprintk(1, "%s()\n", __func__);
+
+	*bandwidth = state->Chan_Bandwidth;
+
+	return 0;
+}
+
+static int mxl5005s_release(struct dvb_frontend *fe)
+{
+	dprintk(1, "%s()\n", __func__);
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+
+static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
+	.info = {
+		.name           = "MaxLinear MXL5005S",
+		.frequency_min  =  48000000,
+		.frequency_max  = 860000000,
+		.frequency_step =     50000,
+	},
+
+	.release       = mxl5005s_release,
+	.init          = mxl5005s_init,
+
+	.set_params    = mxl5005s_set_params,
+	.get_frequency = mxl5005s_get_frequency,
+	.get_bandwidth = mxl5005s_get_bandwidth,
+};
+
+struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+				     struct i2c_adapter *i2c,
+				     struct mxl5005s_config *config)
+{
+	struct mxl5005s_state *state = NULL;
+	dprintk(1, "%s()\n", __func__);
+
+	state = kzalloc(sizeof(struct mxl5005s_state), GFP_KERNEL);
+	if (state == NULL)
+		return NULL;
+
+	state->frontend = fe;
+	state->config = config;
+	state->i2c = i2c;
+	state->current_mode = MXL_QAM;
+
+	printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
+		config->i2c_address);
+
+	memcpy(&fe->ops.tuner_ops, &mxl5005s_tuner_ops,
+		sizeof(struct dvb_tuner_ops));
+
+	fe->tuner_priv = state;
+	return fe;
+}
+EXPORT_SYMBOL(mxl5005s_attach);
+
+MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
new file mode 100644
index 0000000..396db15
--- /dev/null
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -0,0 +1,131 @@
+/*
+    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+    Copyright (C) 2008 MaxLinear
+    Copyright (C) 2008 Steven Toth <stoth@hauppauge.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.
+
+    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.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __MXL5005S_H
+#define __MXL5005S_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct mxl5005s_config {
+
+	/* 7 bit i2c address */
+	u8 i2c_address;
+
+#define IF_FREQ_4570000HZ    4570000
+#define IF_FREQ_4571429HZ    4571429
+#define IF_FREQ_5380000HZ    5380000
+#define IF_FREQ_36000000HZ  36000000
+#define IF_FREQ_36125000HZ  36125000
+#define IF_FREQ_36166667HZ  36166667
+#define IF_FREQ_44000000HZ  44000000
+	u32 if_freq;
+
+#define CRYSTAL_FREQ_4000000HZ    4000000
+#define CRYSTAL_FREQ_16000000HZ  16000000
+#define CRYSTAL_FREQ_25000000HZ  25000000
+#define CRYSTAL_FREQ_28800000HZ  28800000
+	u32 xtal_freq;
+
+#define MXL_DUAL_AGC   0
+#define MXL_SINGLE_AGC 1
+	u8 agc_mode;
+
+#define MXL_TF_DEFAULT	0
+#define MXL_TF_OFF	1
+#define MXL_TF_C	2
+#define MXL_TF_C_H	3
+#define MXL_TF_D	4
+#define MXL_TF_D_L	5
+#define MXL_TF_E	6
+#define MXL_TF_F	7
+#define MXL_TF_E_2	8
+#define MXL_TF_E_NA	9
+#define MXL_TF_G	10
+	u8 tracking_filter;
+
+#define MXL_RSSI_DISABLE	0
+#define MXL_RSSI_ENABLE		1
+	u8 rssi_enable;
+
+#define MXL_CAP_SEL_DISABLE	0
+#define MXL_CAP_SEL_ENABLE	1
+	u8 cap_select;
+
+#define MXL_DIV_OUT_1	0
+#define MXL_DIV_OUT_4	1
+	u8 div_out;
+
+#define MXL_CLOCK_OUT_DISABLE	0
+#define MXL_CLOCK_OUT_ENABLE	1
+	u8 clock_out;
+
+#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200
+#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300
+	u32 output_load;
+
+#define MXL5005S_TOP_5P5   55
+#define MXL5005S_TOP_7P2   72
+#define MXL5005S_TOP_9P2   92
+#define MXL5005S_TOP_11P0 110
+#define MXL5005S_TOP_12P9 129
+#define MXL5005S_TOP_14P7 147
+#define MXL5005S_TOP_16P8 168
+#define MXL5005S_TOP_19P4 194
+#define MXL5005S_TOP_21P2 212
+#define MXL5005S_TOP_23P2 232
+#define MXL5005S_TOP_25P2 252
+#define MXL5005S_TOP_27P1 271
+#define MXL5005S_TOP_29P2 292
+#define MXL5005S_TOP_31P7 317
+#define MXL5005S_TOP_34P9 349
+	u32 top;
+
+#define MXL_ANALOG_MODE  0
+#define MXL_DIGITAL_MODE 1
+	u8 mod_mode;
+
+#define MXL_ZERO_IF 0
+#define MXL_LOW_IF  1
+	u8 if_mode;
+
+	/* Stuff I don't know what to do with */
+	u8 AgcMasterByte;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || \
+	(defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+					    struct i2c_adapter *i2c,
+					    struct mxl5005s_config *config);
+#else
+static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+					    struct i2c_adapter *i2c,
+					    struct mxl5005s_config *config)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_TUNER_MXL5005S */
+
+#endif /* __MXL5005S_H */
+
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index e27a762..42b5f5d 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -227,9 +227,8 @@
 
 	regs[r_cp] &= ~0x20;
 	regs[r_cp] |= ((force & 1) << 5);
-	tda18271_write_regs(fe, r_cp, 1);
 
-	return 0;
+	return tda18271_write_regs(fe, r_cp, 1);
 }
 
 int tda18271_init_regs(struct dvb_frontend *fe)
@@ -487,16 +486,15 @@
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 
-	tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
+	if (tda18271_debug & DBG_ADV)
+		tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
 
 	regs[R_EP3]  &= ~0xe0; /* clear sm, sm_lt, sm_xt */
 	regs[R_EP3]  |= sm    ? (1 << 7) : 0 |
 			sm_lt ? (1 << 6) : 0 |
 			sm_xt ? (1 << 5) : 0;
 
-	tda18271_write_regs(fe, R_EP3, 1);
-
-	return 0;
+	return tda18271_write_regs(fe, R_EP3, 1);
 }
 
 /*---------------------------------------------------------------------*/
@@ -510,7 +508,7 @@
 	u32 div;
 
 	int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	regs[R_MPD]   = (0x77 & pd);
@@ -542,7 +540,7 @@
 	u32 div;
 
 	int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	regs[R_CPD]   = pd;
@@ -566,7 +564,7 @@
 	u8 val;
 
 	int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	regs[R_EP1]  &= ~0x07; /* clear bp filter bits */
@@ -583,7 +581,7 @@
 	u8 val;
 
 	int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	regs[R_EB13] &= ~0x7c; /* clear k & m bits */
@@ -600,7 +598,7 @@
 	u8 val;
 
 	int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	regs[R_EP2]  &= ~0xe0; /* clear rf band bits */
@@ -617,7 +615,7 @@
 	u8 val;
 
 	int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	regs[R_EP2]  &= ~0x1f; /* clear gain taper bits */
@@ -634,7 +632,7 @@
 	u8 val;
 
 	int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	regs[R_EP5] &= ~0x07;
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index b262100..89c01fb 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -51,6 +51,7 @@
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 	u32 N;
 
 	/* update TV broadcast parameters */
@@ -85,7 +86,9 @@
 	/* update rf top / if top */
 	regs[R_EB22]  = 0x00;
 	regs[R_EB22] |= map->rfagc_top;
-	tda18271_write_regs(fe, R_EB22, 1);
+	ret = tda18271_write_regs(fe, R_EB22, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* --------------------------------------------------------------- */
 
@@ -121,7 +124,9 @@
 	/* agc1 has priority on agc2 */
 	regs[R_EB1]  &= ~0x01;
 
-	tda18271_write_regs(fe, R_EB1, 1);
+	ret = tda18271_write_regs(fe, R_EB1, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* --------------------------------------------------------------- */
 
@@ -141,7 +146,9 @@
 		break;
 	}
 
-	tda18271_write_regs(fe, R_TM, 7);
+	ret = tda18271_write_regs(fe, R_TM, 7);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* force charge pump source */
 	charge_pump_source(fe, 1);
@@ -158,9 +165,9 @@
 		regs[R_EP3] &= ~0x04;
 	else
 		regs[R_EP3] |= 0x04;
-	tda18271_write_regs(fe, R_EP3, 1);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EP3, 1);
+fail:
+	return ret;
 }
 
 static int tda18271_read_thermometer(struct dvb_frontend *fe)
@@ -213,11 +220,13 @@
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
 	unsigned char *regs = priv->tda18271_regs;
-	int tm_current, rfcal_comp, approx, i;
+	int tm_current, rfcal_comp, approx, i, ret;
 	u8 dc_over_dt, rf_tab;
 
 	/* power up */
-	tda18271_set_standby_mode(fe, 0, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* read die current temperature */
 	tm_current = tda18271_read_thermometer(fe);
@@ -228,8 +237,8 @@
 	rf_tab = regs[R_EB14];
 
 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
-	if (i < 0)
-		return -EINVAL;
+	if (tda_fail(i))
+		return i;
 
 	if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
 		approx = map[i].rf_a1 *
@@ -250,35 +259,42 @@
 	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
 
 	regs[R_EB14] = approx + rfcal_comp;
-	tda18271_write_regs(fe, R_EB14, 1);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EB14, 1);
+fail:
+	return ret;
 }
 
 static int tda18271_por(struct dvb_frontend *fe)
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
 	/* power up detector 1 */
 	regs[R_EB12] &= ~0x20;
-	tda18271_write_regs(fe, R_EB12, 1);
+	ret = tda18271_write_regs(fe, R_EB12, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 	regs[R_EB18] &= ~0x80; /* turn agc1 loop on */
 	regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */
-	tda18271_write_regs(fe, R_EB18, 1);
+	ret = tda18271_write_regs(fe, R_EB18, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 	regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
 
 	/* POR mode */
-	tda18271_set_standby_mode(fe, 1, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 1, 0, 0);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* disable 1.5 MHz low pass filter */
 	regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
 	regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
-	tda18271_write_regs(fe, R_EB21, 3);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+	return ret;
 }
 
 static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
@@ -389,7 +405,7 @@
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
-	int sgn, bcal, count, wait;
+	int sgn, bcal, count, wait, ret;
 	u8 cid_target;
 	u16 count_limit;
 	u32 freq;
@@ -421,7 +437,9 @@
 	tda18271_write_regs(fe, R_EP2, 1);
 
 	/* read power detection info, stored in EB10 */
-	tda18271_read_extended(fe);
+	ret = tda18271_read_extended(fe);
+	if (tda_fail(ret))
+		return ret;
 
 	/* algorithm initialization */
 	sgn = 1;
@@ -447,7 +465,9 @@
 		tda18271_write_regs(fe, R_EP2, 1);
 
 		/* read power detection info, stored in EB10 */
-		tda18271_read_extended(fe);
+		ret = tda18271_read_extended(fe);
+		if (tda_fail(ret))
+			return ret;
 
 		count += 200;
 
@@ -478,6 +498,7 @@
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
 	/* set standard to digital */
 	regs[R_EP3]  &= ~0x1f; /* clear std bits */
@@ -489,10 +510,14 @@
 	/* update IF output level & IF notch frequency */
 	regs[R_EP4]  &= ~0x1c; /* clear if level bits */
 
-	tda18271_write_regs(fe, R_EP3, 2);
+	ret = tda18271_write_regs(fe, R_EP3, 2);
+	if (tda_fail(ret))
+		goto fail;
 
 	regs[R_EB18] &= ~0x03; /* set agc1_gain to   6 dB */
-	tda18271_write_regs(fe, R_EB18, 1);
+	ret = tda18271_write_regs(fe, R_EB18, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 	regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
 
@@ -500,9 +525,9 @@
 	regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
 	regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
 
-	tda18271_write_regs(fe, R_EB21, 3);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+	return ret;
 }
 
 static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
@@ -521,7 +546,7 @@
 
 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
 
-	if (i < 0)
+	if (tda_fail(i))
 		return i;
 
 	rf_default[RF1] = 1000 * map[i].rf1_def;
@@ -535,6 +560,8 @@
 
 		/* look for optimized calibration frequency */
 		bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
+		if (tda_fail(bcal))
+			return bcal;
 
 		tda18271_calc_rf_cal(fe, &rf_freq[rf]);
 		prog_tab[rf] = regs[R_EB14];
@@ -575,22 +602,29 @@
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned int i;
+	int ret;
 
 	tda_info("tda18271: performing RF tracking filter calibration\n");
 
 	/* wait for die temperature stabilization */
 	msleep(200);
 
-	tda18271_powerscan_init(fe);
+	ret = tda18271_powerscan_init(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* rf band calibration */
-	for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++)
+	for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) {
+		ret =
 		tda18271_rf_tracking_filters_init(fe, 1000 *
 						  priv->rf_cal_state[i].rfmax);
+		if (tda_fail(ret))
+			goto fail;
+	}
 
 	priv->tm_rfcal = tda18271_read_thermometer(fe);
-
-	return 0;
+fail:
+	return ret;
 }
 
 /* ------------------------------------------------------------------ */
@@ -599,6 +633,7 @@
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
 	/* test RF_CAL_OK to see if we need init */
 	if ((regs[R_EP1] & 0x10) == 0)
@@ -607,15 +642,22 @@
 	if (priv->cal_initialized)
 		return 0;
 
-	tda18271_calc_rf_filter_curve(fe);
+	ret = tda18271_calc_rf_filter_curve(fe);
+	if (tda_fail(ret))
+		goto fail;
 
-	tda18271_por(fe);
+	ret = tda18271_por(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 	tda_info("tda18271: RF tracking filter calibration complete\n");
 
 	priv->cal_initialized = true;
-
-	return 0;
+	goto end;
+fail:
+	tda_info("tda18271: RF tracking filter calibration failed!\n");
+end:
+	return ret;
 }
 
 static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
@@ -623,6 +665,7 @@
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 	u32 N = 0;
 
 	/* calculate bp filter */
@@ -671,7 +714,10 @@
 
 	tda18271_calc_main_pll(fe, N);
 
-	tda18271_write_regs(fe, R_EP3, 11);
+	ret = tda18271_write_regs(fe, R_EP3, 11);
+	if (tda_fail(ret))
+		return ret;
+
 	msleep(5); /* RF tracking filter calibration initialization */
 
 	/* search for K,M,CO for RF calibration */
@@ -719,45 +765,56 @@
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
-	tda18271_read_regs(fe);
+	ret = tda18271_read_regs(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* test IR_CAL_OK to see if we need init */
 	if ((regs[R_EP1] & 0x08) == 0)
-		tda18271_init_regs(fe);
-
-	return 0;
+		ret = tda18271_init_regs(fe);
+fail:
+	return ret;
 }
 
 static int tda18271_init(struct dvb_frontend *fe)
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret;
 
 	mutex_lock(&priv->lock);
 
 	/* power up */
-	tda18271_set_standby_mode(fe, 0, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+	if (tda_fail(ret))
+		goto fail;
 
 	/* initialization */
-	tda18271_ir_cal_init(fe);
+	ret = tda18271_ir_cal_init(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 	if (priv->id == TDA18271HDC2)
 		tda18271c2_rf_cal_init(fe);
-
+fail:
 	mutex_unlock(&priv->lock);
 
-	return 0;
+	return ret;
 }
 
 static int tda18271_tune(struct dvb_frontend *fe,
 			 struct tda18271_std_map_item *map, u32 freq, u32 bw)
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret;
 
 	tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
 		freq, map->if_freq, bw, map->agc_mode, map->std);
 
-	tda18271_init(fe);
+	ret = tda18271_init(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 	mutex_lock(&priv->lock);
 
@@ -769,11 +826,11 @@
 		tda18271c2_rf_tracking_filters_correction(fe, freq);
 		break;
 	}
-	tda18271_channel_configuration(fe, map, freq, bw);
+	ret = tda18271_channel_configuration(fe, map, freq, bw);
 
 	mutex_unlock(&priv->lock);
-
-	return 0;
+fail:
+	return ret;
 }
 
 /* ------------------------------------------------------------------ */
@@ -837,7 +894,7 @@
 
 	ret = tda18271_tune(fe, map, freq, bw);
 
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	priv->frequency = freq;
@@ -893,7 +950,7 @@
 
 	ret = tda18271_tune(fe, map, freq, 0);
 
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 
 	priv->frequency = freq;
@@ -905,16 +962,17 @@
 static int tda18271_sleep(struct dvb_frontend *fe)
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret;
 
 	mutex_lock(&priv->lock);
 
 	/* standby mode w/ slave tuner output
 	 * & loop thru & xtal oscillator on */
-	tda18271_set_standby_mode(fe, 1, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 1, 0, 0);
 
 	mutex_unlock(&priv->lock);
 
-	return 0;
+	return ret;
 }
 
 static int tda18271_release(struct dvb_frontend *fe)
@@ -1095,10 +1153,10 @@
 		if (cfg)
 			priv->small_i2c = cfg->small_i2c;
 
-		if (tda18271_get_id(fe) < 0)
+		if (tda_fail(tda18271_get_id(fe)))
 			goto fail;
 
-		if (tda18271_assign_map_layout(fe) < 0)
+		if (tda_fail(tda18271_assign_map_layout(fe)))
 			goto fail;
 
 		mutex_lock(&priv->lock);
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bc5eb3..81a7393 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -153,6 +153,15 @@
 #define tda_reg(fmt, arg...)  dprintk(KERN_DEBUG, DBG_REG,  fmt, ##arg)
 #define tda_cal(fmt, arg...)  dprintk(KERN_DEBUG, DBG_CAL,  fmt, ##arg)
 
+#define tda_fail(ret)							     \
+({									     \
+	int __ret;							     \
+	__ret = (ret < 0);						     \
+	if (__ret)							     \
+		tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\
+	__ret;								     \
+})
+
 /*---------------------------------------------------------------------*/
 
 enum tda18271_map_type {
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c
index f6e7d7a..1f56463 100644
--- a/drivers/media/common/tuners/tea5767.c
+++ b/drivers/media/common/tuners/tea5767.c
@@ -373,14 +373,14 @@
 
 	if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
 		printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
-		return EINVAL;
+		return -EINVAL;
 	}
 
 	/* If all bytes are the same then it's a TV tuner and not a tea5767 */
 	if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
 	    buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
 		printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
-		return EINVAL;
+		return -EINVAL;
 	}
 
 	/*  Status bytes:
@@ -390,7 +390,7 @@
 	 */
 	if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
 		printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
-		return EINVAL;
+		return -EINVAL;
 	}
 
 
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 43d35bd..ceae6db 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -212,7 +212,7 @@
 	dprintk(1, "%s()\n", __func__);
 
 	if (priv->cfg->tuner_callback) {
-		ret = priv->cfg->tuner_callback(priv->cfg->priv,
+		ret = priv->cfg->tuner_callback(priv->devptr,
 						XC5000_TUNER_RESET, 0);
 		if (ret)
 			printk(KERN_ERR "xc5000: reset failed\n");
@@ -900,9 +900,9 @@
 	.get_status	   = xc5000_get_status
 };
 
-struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
-	struct i2c_adapter *i2c,
-	struct xc5000_config *cfg)
+struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
+				   struct i2c_adapter *i2c,
+				   struct xc5000_config *cfg, void *devptr)
 {
 	struct xc5000_priv *priv = NULL;
 	u16 id = 0;
@@ -916,6 +916,7 @@
 	priv->cfg = cfg;
 	priv->bandwidth = BANDWIDTH_6_MHZ;
 	priv->i2c = i2c;
+	priv->devptr = devptr;
 
 	/* Check if firmware has been loaded. It is possible that another
 	   instance of the driver has loaded the firmware.
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index 0ee80f9..c910715 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -31,29 +31,31 @@
 	u8   i2c_address;
 	u32  if_khz;
 
-	/* For each bridge framework, when it attaches either analog or digital,
-	 * it has to store a reference back to its _core equivalent structure,
-	 * so that it can service the hardware by steering gpio's etc.
-	 * Each bridge implementation is different so cast priv accordingly.
-	 * The xc5000 driver cares not for this value, other than ensuring
-	 * it's passed back to a bridge during tuner_callback().
-	 */
-	void *priv;
 	int  (*tuner_callback) (void *priv, int command, int arg);
 };
 
 /* xc5000 callback command */
 #define XC5000_TUNER_RESET		0
 
+/* For each bridge framework, when it attaches either analog or digital,
+ * it has to store a reference back to its _core equivalent structure,
+ * so that it can service the hardware by steering gpio's etc.
+ * Each bridge implementation is different so cast devptr accordingly.
+ * The xc5000 driver cares not for this value, other than ensuring
+ * it's passed back to a bridge during tuner_callback().
+ */
+
 #if defined(CONFIG_MEDIA_TUNER_XC5000) || \
     (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
 extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 					  struct i2c_adapter *i2c,
-					  struct xc5000_config *cfg);
+					  struct xc5000_config *cfg,
+					  void *devptr);
 #else
 static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 						 struct i2c_adapter *i2c,
-						 struct xc5000_config *cfg)
+						 struct xc5000_config *cfg,
+						 void *devptr)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
index 13b2d19..ecebfe4 100644
--- a/drivers/media/common/tuners/xc5000_priv.h
+++ b/drivers/media/common/tuners/xc5000_priv.h
@@ -31,6 +31,8 @@
 	u8  video_standard;
 	u8  rf_mode;
 	u8  fwloaded;
+
+	void *devptr;
 };
 
 #endif
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 7b0ea3b..f9d0876 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -634,7 +634,7 @@
 	}
 
 	/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
-	fc->fe = dvb_attach(vp310_mt312_attach,
+	fc->fe = dvb_attach(mt312_attach,
 		&skystar23_samsung_tbdu18132_config, i2c);
 	if (fc->fe != NULL) {
 		ops = &fc->fe->ops;
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index d1239b8..7588db1 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -1,6 +1,7 @@
 config DVB_BT8XX
 	tristate "BT8xx based PCI cards"
 	depends on DVB_CORE && PCI && I2C && VIDEO_BT848
+	depends on HOTPLUG	# due to FW_LOADER
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_SP887X if !DVB_FE_CUSTOMISE
 	select DVB_NXT6000 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 3d778c5..c03513b 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -1,6 +1,6 @@
 config DVB_CINERGYT2
 	tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
-	depends on DVB_CORE && USB
+	depends on DVB_CORE && USB && INPUT
 	help
 	  Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
 
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 8cbdb0e..588fbe1 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -910,15 +910,21 @@
 	int curdelay = 100000000;
 	int slot;
 
+	/* Beware of too high polling frequency, because one polling
+	 * call might take several hundred milliseconds until timeout!
+	 */
 	for (slot = 0; slot < ca->slot_count; slot++) {
 		switch (ca->slot_info[slot].slot_state) {
 		default:
 		case DVB_CA_SLOTSTATE_NONE:
+			delay = HZ * 60;  /* 60s */
+			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+				delay = HZ * 5;  /* 5s */
+			break;
 		case DVB_CA_SLOTSTATE_INVALID:
-			delay = HZ * 60;
-			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
-				delay = HZ / 10;
-			}
+			delay = HZ * 60;  /* 60s */
+			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+				delay = HZ / 10;  /* 100ms */
 			break;
 
 		case DVB_CA_SLOTSTATE_UNINITIALISED:
@@ -926,19 +932,17 @@
 		case DVB_CA_SLOTSTATE_VALIDATE:
 		case DVB_CA_SLOTSTATE_WAITFR:
 		case DVB_CA_SLOTSTATE_LINKINIT:
-			delay = HZ / 10;
+			delay = HZ / 10;  /* 100ms */
 			break;
 
 		case DVB_CA_SLOTSTATE_RUNNING:
-			delay = HZ * 60;
-			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
-				delay = HZ / 10;
-			}
+			delay = HZ * 60;  /* 60s */
+			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+				delay = HZ / 10;  /* 100ms */
 			if (ca->open) {
 				if ((!ca->slot_info[slot].da_irq_supported) ||
-				    (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) {
-					delay = HZ / 10;
-				}
+				    (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
+					delay = HZ / 10;  /* 100ms */
 			}
 			break;
 		}
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 4c1cff9..cf4584e 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -1,6 +1,7 @@
 config DVB_USB
 	tristate "Support for various USB DVB devices"
 	depends on DVB_CORE && USB && I2C
+	depends on HOTPLUG	# due to FW_LOADER
 	select FW_LOADER
 	help
 	  By enabling this you will be able to choose the various supported
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 6d23846..c20553c 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -30,7 +30,7 @@
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
 config DVB_MT312
-	tristate "Zarlink VP310/MT312 based"
+	tristate "Zarlink VP310/MT312/ZL10313 based"
 	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
@@ -97,7 +97,7 @@
 
 config DVB_SP8870
 	tristate "Spase sp8870 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
@@ -110,7 +110,7 @@
 
 config DVB_SP887X
 	tristate "Spase sp887x based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
@@ -144,7 +144,7 @@
 
 config DVB_TDA1004X
 	tristate "Philips TDA10045H/TDA10046H based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
@@ -211,7 +211,7 @@
 
 config DVB_TDA10048
 	tristate "Philips TDA10048HN based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
@@ -253,7 +253,7 @@
 
 config DVB_NXT200X
 	tristate "NxtWave Communications NXT2002/NXT2004 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
@@ -268,7 +268,7 @@
 
 config DVB_OR51211
 	tristate "Oren OR51211 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
@@ -281,7 +281,7 @@
 
 config DVB_OR51132
 	tristate "Oren OR51132 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
@@ -297,7 +297,7 @@
 
 config DVB_BCM3510
 	tristate "Broadcom BCM3510"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c
index 04c562c..600dad6 100644
--- a/drivers/media/dvb/frontends/itd1000.c
+++ b/drivers/media/dvb/frontends/itd1000.c
@@ -195,7 +195,7 @@
 	}
 }
 
-struct {
+static const struct {
 	u32 freq;
 	u8 values[10]; /* RFTR, RFST1 - RFST9 */
 } itd1000_fre_values[] = {
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index 081ca33..5ac9b15 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -737,7 +737,7 @@
 }
 
 #define MT312_SYS_CLK		90000000UL	/* 90 MHz */
-static struct dvb_frontend_ops vp310_mt312_ops = {
+static struct dvb_frontend_ops mt312_ops = {
 
 	.info = {
 		.name = "Zarlink ???? DVB-S",
@@ -776,7 +776,7 @@
 	.set_voltage = mt312_set_voltage,
 };
 
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
 					struct i2c_adapter *i2c)
 {
 	struct mt312_state *state = NULL;
@@ -795,7 +795,7 @@
 		goto error;
 
 	/* create dvb_frontend */
-	memcpy(&state->frontend.ops, &vp310_mt312_ops,
+	memcpy(&state->frontend.ops, &mt312_ops,
 		sizeof(struct dvb_frontend_ops));
 	state->frontend.demodulator_priv = state;
 
@@ -827,12 +827,13 @@
 	kfree(state);
 	return NULL;
 }
-EXPORT_SYMBOL(vp310_mt312_attach);
+EXPORT_SYMBOL(mt312_attach);
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
 MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
 MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index de796ea..29e3bb5 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -37,10 +37,10 @@
 };
 
 #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
 					struct i2c_adapter *i2c);
 #else
-static inline struct dvb_frontend *vp310_mt312_attach(
+static inline struct dvb_frontend *mt312_attach(
 	const struct mt312_config *config, struct i2c_adapter *i2c)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index ae882432..d4339b1 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -5,6 +5,7 @@
 config DVB_AV7110
 	tristate "AV7110 cards"
 	depends on DVB_CORE && PCI && I2C
+	depends on HOTPLUG
 	select FW_LOADER if !DVB_AV7110_FIRMWARE
 	select TTPCI_EEPROM
 	select VIDEO_SAA7146_VV
@@ -123,6 +124,7 @@
 	depends on DVB_BUDGET_CORE && I2C
 	select VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
+	depends on HOTPLUG	# dependency of FW_LOADER
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
index 8361101..0712899 100644
--- a/drivers/media/dvb/ttusb-dec/Kconfig
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -1,6 +1,7 @@
 config DVB_TTUSB_DEC
 	tristate "Technotrend/Hauppauge USB DEC devices"
 	depends on DVB_CORE && USB
+	depends on HOTPLUG	# due to FW_LOADER
 	select FW_LOADER
 	select CRC32
 	help
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fe743aa..89d8d37 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -44,6 +44,10 @@
 	tristate
 	depends on I2C
 
+config VIDEO_TUNER
+	tristate
+	depends on MEDIA_TUNER
+
 #
 # Multimedia Video device configuration
 #
@@ -690,7 +694,7 @@
 	tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
 	depends on PCI && VIDEO_V4L1 && I2C
 	select VIDEO_SAA7146_VV
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
@@ -906,7 +910,7 @@
 
 config SOC_CAMERA_MT9M001
 	tristate "mt9m001 support"
-	depends on SOC_CAMERA
+	depends on SOC_CAMERA && I2C
 	select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
 	help
 	  This driver supports MT9M001 cameras from Micron, monochrome
@@ -921,7 +925,7 @@
 
 config SOC_CAMERA_MT9V022
 	tristate "mt9v022 support"
-	depends on SOC_CAMERA
+	depends on SOC_CAMERA && I2C
 	select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
 	help
 	  This driver supports MT9V022 cameras from Micron
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index a352c6e..dff0d6a 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -84,7 +84,7 @@
 obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
-obj-$(CONFIG_MEDIA_TUNER) += tuner.o
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o
 
 obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
 obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index cab277f..def10d0 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -1,8 +1,9 @@
 
 config VIDEO_AU0828
 	tristate "Auvitek AU0828 support"
-       depends on VIDEO_DEV && I2C && INPUT && DVB_CORE
+	depends on VIDEO_DEV && I2C && INPUT && DVB_CORE && USB
 	select I2C_ALGOBIT
+	select VIDEO_TVEEPROM
 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
 	---help---
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 1371b4e..c86a5f17 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -337,12 +337,10 @@
 		dvb->frontend = dvb_attach(au8522_attach,
 				&hauppauge_hvr950q_config,
 				&dev->i2c_adap);
-		if (dvb->frontend != NULL) {
-			hauppauge_hvr950q_tunerconfig.priv = dev;
+		if (dvb->frontend != NULL)
 			dvb_attach(xc5000_attach, dvb->frontend,
 				&dev->i2c_adap,
-				&hauppauge_hvr950q_tunerconfig);
-		}
+				&hauppauge_hvr950q_tunerconfig, dev);
 		break;
 	default:
 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index 7431ef6..24a34fc 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -1,12 +1,13 @@
 config VIDEO_BT848
 	tristate "BT848 Video For Linux"
 	depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
+	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEOBUF_DMA_SG
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index acc4b47..5f94269 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -1,14 +1,17 @@
 config VIDEO_CX18
 	tristate "Conexant cx23418 MPEG encoder support"
 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
+	depends on INPUT	# due to VIDEO_IR
+	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_CX2341X
 	select VIDEO_CS5345
 	select DVB_S5H1409
+	select MEDIA_TUNER_MXL5005S
 	---help---
 	  This is a video4linux driver for Conexant cx23418 based
 	  PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index f5e3ba1..553adbf 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -47,11 +47,12 @@
 static const struct cx18_card cx18_card_hvr1600_esmt = {
 	.type = CX18_CARD_HVR_1600_ESMT,
 	.name = "Hauppauge HVR-1600",
-	.comment = "DVB & VBI are not yet supported\n",
+	.comment = "VBI is not yet supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_muxer = CX18_HW_CS5345,
-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
+	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+		  CX18_HW_CS5345 | CX18_HW_DVB,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
@@ -86,11 +87,12 @@
 static const struct cx18_card cx18_card_hvr1600_samsung = {
 	.type = CX18_CARD_HVR_1600_SAMSUNG,
 	.name = "Hauppauge HVR-1600 (Preproduction)",
-	.comment = "DVB & VBI are not yet supported\n",
+	.comment = "VBI is not yet supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_muxer = CX18_HW_CS5345,
-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
+	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+		  CX18_HW_CS5345 | CX18_HW_DVB,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
@@ -134,14 +136,15 @@
 static const struct cx18_card cx18_card_h900 = {
 	.type = CX18_CARD_COMPRO_H900,
 	.name = "Compro VideoMate H900",
-	.comment = "Not yet supported!\n",
-	.v4l2_capabilities = 0,
+	.comment = "DVB & VBI are not yet supported\n",
+	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_all = CX18_HW_TUNER,
 	.video_inputs = {
-		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
-		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
-		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
+		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE2 },
+		{ CX18_CARD_INPUT_SVIDEO1,    1,
+			CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
+		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
 	},
 	.audio_inputs = {
 		{ CX18_CARD_INPUT_AUD_TUNER,
@@ -163,6 +166,7 @@
 		.tune_lane = 0,
 		.initial_emrs = 0,
 	},
+	.xceive_pin = 15,
 	.pci_list = cx18_pci_h900,
 	.i2c = &cx18_i2c_std,
 };
@@ -200,8 +204,6 @@
 		/* XC3028 tuner */
 		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
 	},
-	/* tuner reset */
-	.gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
 	.ddr = {
 		/* Probably Samsung K4D263238G-VC33 memory */
 		.chip_config = 0x003,
@@ -211,6 +213,7 @@
 		.tune_lane = 0,
 		.initial_emrs = 2,
 	},
+	.xceive_pin = 15,
 	.pci_list = cx18_pci_mpc718,
 	.i2c = &cx18_i2c_std,
 };
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index bca249b..bccb67f 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -114,8 +114,8 @@
 /* The mask is the set of bits used by the operation */
 
 struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
-	u16 direction; 	/* DIR setting. Leave to 0 if no init is needed */
-	u16 initial_value;
+	u32 direction; 	/* DIR setting. Leave to 0 if no init is needed */
+	u32 initial_value;
 };
 
 struct cx18_card_tuner {
@@ -153,6 +153,7 @@
 	struct cx18_card_audio_input radio_input;
 
 	/* GPIO card-specific settings */
+	u8 xceive_pin; 		/* XCeive tuner GPIO reset pin */
 	struct cx18_gpio_init 		gpio_init;
 
 	struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 8f5ed9b..0dd4e05 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -164,16 +164,6 @@
 
 MODULE_VERSION(CX18_VERSION);
 
-int cx18_waitq(wait_queue_head_t *waitq)
-{
-	DEFINE_WAIT(wait);
-
-	prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
-	schedule();
-	finish_wait(waitq, &wait);
-	return signal_pending(current) ? -EINTR : 0;
-}
-
 /* Generic utility functions */
 int cx18_msleep_timeout(unsigned int msecs, int intr)
 {
@@ -220,13 +210,13 @@
 
 	/* Many thanks to Steven Toth from Hauppauge for providing the
 	   model numbers */
+	/* Note: the Samsung memory models cannot be reliably determined
+	   from the model number. Use the cardtype module option if you
+	   have one of these preproduction models. */
 	switch (tv.model) {
-	case 74000 ... 74099:
+	case 74000 ... 74999:
 		cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
 		break;
-	case 74700 ... 74799:
-		cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
-		break;
 	case 0:
 		CX18_ERR("Invalid EEPROM\n");
 		return;
@@ -548,6 +538,7 @@
 	return 0;
 }
 
+#ifdef MODULE
 static u32 cx18_request_module(struct cx18 *cx, u32 hw,
 		const char *name, u32 id)
 {
@@ -560,12 +551,14 @@
 	CX18_DEBUG_INFO("Loaded module %s\n", name);
 	return hw;
 }
+#endif
 
 static void cx18_load_and_init_modules(struct cx18 *cx)
 {
 	u32 hw = cx->card->hw_all;
 	int i;
 
+#ifdef MODULE
 	/* load modules */
 #ifndef CONFIG_MEDIA_TUNER
 	hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
@@ -573,6 +566,7 @@
 #ifndef CONFIG_VIDEO_CS5345
 	hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
 #endif
+#endif
 
 	/* check which i2c devices are actually found */
 	for (i = 0; i < 32; i++) {
@@ -613,7 +607,7 @@
 	}
 
 	cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
-	if (cx == 0) {
+	if (!cx) {
 		spin_unlock(&cx18_cards_lock);
 		return -ENOMEM;
 	}
@@ -801,7 +795,7 @@
 	return 0;
 
 free_streams:
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 1);
 free_irq:
 	free_irq(cx->dev->irq, (void *)cx);
 free_i2c:
@@ -904,14 +898,13 @@
 
 	cx18_halt_firmware(cx);
 
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 1);
 
 	exit_cx18_i2c(cx);
 
 	free_irq(cx->dev->irq, (void *)cx);
 
-	if (cx->dev)
-		cx18_iounmap(cx);
+	cx18_iounmap(cx);
 
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 2ee9391..a2a6c58 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -444,9 +444,6 @@
 /* Return non-zero if a signal is pending */
 int cx18_msleep_timeout(unsigned int msecs, int intr);
 
-/* Wait on queue, returns -EINTR if interrupted */
-int cx18_waitq(wait_queue_head_t *waitq);
-
 /* Read Hauppauge eeprom */
 struct tveeprom; /* forward reference */
 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 65efe69..c974417 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -24,25 +24,27 @@
 #include "cx18-streams.h"
 #include "cx18-cards.h"
 #include "s5h1409.h"
-
-/* Wait until the MXL500X driver is merged */
-#ifdef HAVE_MXL500X
-#include "mxl500x.h"
-#endif
+#include "mxl5005s.h"
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
 
-#ifdef HAVE_MXL500X
-static struct mxl500x_config hauppauge_hvr1600_tuner = {
-	.delsys    = MXL500x_MODE_ATSC,
-	.octf      = MXL500x_OCTF_CH,
-	.xtal_freq = 16000000,
-	.iflo_freq = 5380000,
-	.ref_freq  = 322800000,
-	.rssi_ena  = MXL_RSSI_ENABLE,
-	.addr      = 0xC6 >> 1,
+static struct mxl5005s_config hauppauge_hvr1600_tuner = {
+	.i2c_address     = 0xC6 >> 1,
+	.if_freq         = IF_FREQ_5380000HZ,
+	.xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+	.agc_mode        = MXL_SINGLE_AGC,
+	.tracking_filter = MXL_TF_C_H,
+	.rssi_enable     = MXL_RSSI_ENABLE,
+	.cap_select      = MXL_CAP_SEL_ENABLE,
+	.div_out         = MXL_DIV_OUT_4,
+	.clock_out       = MXL_CLOCK_OUT_DISABLE,
+	.output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+	.top		 = MXL5005S_TOP_25P2,
+	.mod_mode        = MXL_DIGITAL_MODE,
+	.if_mode         = MXL_ZERO_IF,
+	.AgcMasterByte   = 0x00,
 };
 
 static struct s5h1409_config hauppauge_hvr1600_config = {
@@ -55,7 +57,6 @@
 	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
 
 };
-#endif
 
 static int dvb_register(struct cx18_stream *stream);
 
@@ -252,21 +253,18 @@
 	int ret = 0;
 
 	switch (cx->card->type) {
-/* Wait until the MXL500X driver is merged */
-#ifdef HAVE_MXL500X
 	case CX18_CARD_HVR_1600_ESMT:
 	case CX18_CARD_HVR_1600_SAMSUNG:
 		dvb->fe = dvb_attach(s5h1409_attach,
 			&hauppauge_hvr1600_config,
 			&cx->i2c_adap[0]);
 		if (dvb->fe != NULL) {
-			dvb_attach(mxl500x_attach, dvb->fe,
-				&hauppauge_hvr1600_tuner,
-				&cx->i2c_adap[0]);
+			dvb_attach(mxl5005s_attach, dvb->fe,
+				&cx->i2c_adap[0],
+				&hauppauge_hvr1600_tuner);
 			ret = 0;
 		}
 		break;
-#endif
 	default:
 		/* No Digital Tv Support */
 		break;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 6930306..0b3141d 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -39,7 +39,7 @@
    associated VBI streams are also automatically claimed.
    Possible error returns: -EBUSY if someone else has claimed
    the stream or 0 on success. */
-int cx18_claim_stream(struct cx18_open_id *id, int type)
+static int cx18_claim_stream(struct cx18_open_id *id, int type)
 {
 	struct cx18 *cx = id->cx;
 	struct cx18_stream *s = &cx->streams[type];
@@ -87,7 +87,7 @@
 
 /* This function releases a previously claimed stream. It will take into
    account associated VBI streams. */
-void cx18_release_stream(struct cx18_stream *s)
+static void cx18_release_stream(struct cx18_stream *s)
 {
 	struct cx18 *cx = s->cx;
 	struct cx18_stream *s_vbi;
@@ -662,6 +662,8 @@
 	for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
 		/* find out which stream this open was on */
 		for (y = 0; y < CX18_MAX_STREAMS; y++) {
+			if (cx18_cards[x] == NULL)
+				continue;
 			s = &cx18_cards[x]->streams[y];
 			if (s->v4l2dev && s->v4l2dev->minor == minor) {
 				cx = cx18_cards[x];
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
index 16cdafb..46da028 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -34,12 +34,3 @@
 void cx18_mute(struct cx18 *cx);
 void cx18_unmute(struct cx18 *cx);
 
-/* Utilities */
-
-/* Try to claim a stream for the filehandle. Return 0 on success,
-   -EBUSY if stream already claimed. Once a stream is claimed, it
-   remains claimed until the associated filehandle is closed. */
-int cx18_claim_stream(struct cx18_open_id *id, int type);
-
-/* Release a previously claimed stream. */
-void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 19253e6..bb8bc86 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -35,6 +35,9 @@
 #define CX18_REG_GPIO_OUT2   0xc78104
 #define CX18_REG_GPIO_DIR2   0xc7810c
 
+static u32 gpio_dir;
+static u32 gpio_val;
+
 /*
  * HVR-1600 GPIO pins, courtesy of Hauppauge:
  *
@@ -44,31 +47,53 @@
  * gpio13: cs5345 reset pin
 */
 
+static void gpio_write(struct cx18 *cx)
+{
+	write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
+	write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff),
+			CX18_REG_GPIO_OUT1);
+	write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2);
+	write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16),
+			CX18_REG_GPIO_OUT2);
+}
+
 void cx18_gpio_init(struct cx18 *cx)
 {
-	if (cx->card->gpio_init.direction == 0)
+	gpio_dir = cx->card->gpio_init.direction;
+	gpio_val = cx->card->gpio_init.initial_value;
+
+	if (gpio_dir == 0)
 		return;
 
-	CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
-		   read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1));
+	gpio_dir |= 1 << cx->card->xceive_pin;
+	gpio_val |= 1 << cx->card->xceive_pin;
 
-	/* init output data then direction */
-	write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
-	write_reg(0, CX18_REG_GPIO_DIR2);
-	write_reg((cx->card->gpio_init.direction << 16) |
-			cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
-	write_reg(0, CX18_REG_GPIO_OUT2);
+	CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
+		   read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
+		   read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
+
+	gpio_write(cx);
 }
 
 /* Xceive tuner reset function */
 int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
 {
 	struct i2c_algo_bit_data *algo = dev;
-	struct cx18 *cx = algo->data;
-/*	int curdir, curout;*/
+	struct cx18_i2c_algo_callback_data *cb_data = algo->data;
+	struct cx18 *cx = cb_data->cx;
 
 	if (cmd != XC2028_TUNER_RESET)
 		return 0;
 	CX18_DEBUG_INFO("Resetting tuner\n");
+
+	gpio_dir |= 1 << cx->card->xceive_pin;
+	gpio_val &= ~(1 << cx->card->xceive_pin);
+
+	gpio_write(cx);
+	schedule_timeout_interruptible(msecs_to_jiffies(1));
+
+	gpio_val |= 1 << cx->card->xceive_pin;
+	gpio_write(cx);
+	schedule_timeout_interruptible(msecs_to_jiffies(1));
 	return 0;
 }
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 18c88d1..4f08a40 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -25,6 +25,7 @@
 #include "cx18-cards.h"
 #include "cx18-gpio.h"
 #include "cx18-av-core.h"
+#include "cx18-i2c.h"
 
 #include <media/ir-kbd-i2c.h>
 
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 65af1bb..6990b77 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -26,17 +26,6 @@
 #include "cx18-queue.h"
 #include "cx18-scb.h"
 
-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
-		const char __user *src, int copybytes)
-{
-	if (s->buf_size - buf->bytesused < copybytes)
-		copybytes = s->buf_size - buf->bytesused;
-	if (copy_from_user(buf->buf + buf->bytesused, src, copybytes))
-		return -EFAULT;
-	buf->bytesused += copybytes;
-	return copybytes;
-}
-
 void cx18_buf_swap(struct cx18_buffer *buf)
 {
 	int i;
@@ -159,8 +148,9 @@
    -ENOMEM is returned if the buffers could not be obtained, 0 if all
    buffers where obtained from the 'from' list and if non-zero then
    the number of stolen buffers is returned. */
-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
-	struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes)
+static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
+			   struct cx18_queue *steal, struct cx18_queue *to,
+			   int needed_bytes)
 {
 	unsigned long flags;
 	int rc = 0;
@@ -239,12 +229,12 @@
 
 	/* allocate stream buffers. Initially all buffers are in q_free. */
 	for (i = 0; i < s->buffers; i++) {
-		struct cx18_buffer *buf =
-			kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL);
+		struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
+						GFP_KERNEL|__GFP_NOWARN);
 
 		if (buf == NULL)
 			break;
-		buf->buf = kmalloc(s->buf_size, GFP_KERNEL);
+		buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
 		if (buf->buf == NULL) {
 			kfree(buf);
 			break;
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index f86c8a6..91423b9 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -39,8 +39,6 @@
 				s->buf_size, s->dma);
 }
 
-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
-	const char __user *src, int copybytes);
 void cx18_buf_swap(struct cx18_buffer *buf);
 
 /* cx18_queue utility functions */
@@ -48,8 +46,6 @@
 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
 	struct cx18_queue *q);
 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
-       struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes);
 struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
 	u32 bytesused);
 void cx18_flush_queues(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index afb141b..4ca9d84 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -218,7 +218,7 @@
 		return 0;
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 0);
 	return -ENOMEM;
 }
 
@@ -296,12 +296,12 @@
 		return 0;
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 1);
 	return -ENOMEM;
 }
 
 /* Unregister v4l2 devices */
-void cx18_streams_cleanup(struct cx18 *cx)
+void cx18_streams_cleanup(struct cx18 *cx, int unregister)
 {
 	struct video_device *vdev;
 	int type;
@@ -319,8 +319,11 @@
 
 		cx18_stream_free(&cx->streams[type]);
 
-		/* Unregister device */
-		video_unregister_device(vdev);
+		/* Unregister or release device */
+		if (unregister)
+			video_unregister_device(vdev);
+		else
+			video_device_release(vdev);
 	}
 }
 
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 8c7ba7d..f327e94 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -24,7 +24,7 @@
 u32 cx18_find_handle(struct cx18 *cx);
 int cx18_streams_setup(struct cx18 *cx);
 int cx18_streams_register(struct cx18 *cx);
-void cx18_streams_cleanup(struct cx18 *cx);
+void cx18_streams_cleanup(struct cx18 *cx, int unregister);
 
 /* Capture related */
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index cadf936..7bf14c9 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -1,18 +1,20 @@
 config VIDEO_CX23885
 	tristate "Conexant cx23885 (2388x successor) support"
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
+	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select VIDEO_BTCX
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_IR
 	select VIDEOBUF_DVB
 	select VIDEO_CX25840
+	select VIDEO_CX2341X
+	select DVB_DIB7000P if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
 	select DVB_S5H1409 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
-	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 6ebf587..20e05f2 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -200,6 +200,10 @@
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1200,
 	}, {
 		.subvendor = 0x0070,
+		.subdevice = 0x71d3,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1200,
+	}, {
+		.subvendor = 0x0070,
 		.subdevice = 0x8101,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1700,
 	}, {
@@ -245,6 +249,33 @@
 	/* Make sure we support the board model */
 	switch (tv.model)
 	{
+	case 71009:
+		/* WinTV-HVR1200 (PCIe, Retail, full height)
+		 * DVB-T and basic analog */
+	case 71359:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71439:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71449:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
+	case 71939:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71949:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
+	case 71959:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
+	case 71979:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71999:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
 	case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
 	case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */
 	case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
@@ -263,8 +294,11 @@
 	case 80019:
 		/* WinTV-HVR1400 (Express Card, Retail, IR,
 		 * DVB-T and Basic analog */
+	case 81509:
+		/* WinTV-HVR1700 (PCIe, OEM, No IR, half height)
+		 * DVB-T and MPEG2 HW Encoder */
 	case 81519:
-		/* WinTV-HVR1700 (PCIe, Retail, No IR, half height,
+		/* WinTV-HVR1700 (PCIe, OEM, No IR, full height)
 		 * DVB-T and MPEG2 HW Encoder */
 		break;
 	default:
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index f056497..022aa39 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -37,7 +37,6 @@
 #include "lgdt330x.h"
 #include "xc5000.h"
 #include "tda10048.h"
-#include "dvb-pll.h"
 #include "tuner-xc2028.h"
 #include "tuner-simple.h"
 #include "dib7000p.h"
@@ -385,12 +384,10 @@
 		port->dvb.frontend = dvb_attach(s5h1409_attach,
 						&hauppauge_hvr1500q_config,
 						&dev->i2c_bus[0].i2c_adap);
-		if (port->dvb.frontend != NULL) {
-			hauppauge_hvr1500q_tunerconfig.priv = i2c_bus;
+		if (port->dvb.frontend != NULL)
 			dvb_attach(xc5000_attach, port->dvb.frontend,
 				&i2c_bus->i2c_adap,
-				&hauppauge_hvr1500q_tunerconfig);
-		}
+				&hauppauge_hvr1500q_tunerconfig, i2c_bus);
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 		i2c_bus = &dev->i2c_bus[1];
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
index 7cf29a0..448f4cd 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/video/cx25840/Kconfig
@@ -1,6 +1,7 @@
 config VIDEO_CX25840
 	tristate "Conexant CX2584x audio/video decoders"
 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+	depends on HOTPLUG # due to FW_LOADER
 	select FW_LOADER
 	---help---
 	  Support for the Conexant CX2584x audio/video decoders.
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index b0d7d6a..10e20d8 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -2,10 +2,9 @@
 	tristate "Conexant 2388x (bt878 successor) support"
 	depends on VIDEO_DEV && PCI && I2C && INPUT
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEOBUF_DMA_SG
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_IR
 	select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
@@ -34,8 +33,9 @@
 
 config VIDEO_CX88_BLACKBIRD
 	tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
-	depends on VIDEO_CX88
+	depends on VIDEO_CX88 && HOTPLUG
 	select VIDEO_CX2341X
+	select FW_LOADER
 	---help---
 	  This adds support for MPEG encoder cards based on the
 	  Blackbird reference design, using the Conexant 2388x
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 1c7fe68..d96173f 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -509,9 +509,6 @@
 	if (!fe) {
 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 		       dev->core->name);
-		dvb_frontend_detach(dev->dvb.frontend);
-		dvb_unregister_frontend(dev->dvb.frontend);
-		dev->dvb.frontend = NULL;
 		return -EINVAL;
 	}
 
@@ -523,20 +520,23 @@
 
 static int dvb_register(struct cx8802_dev *dev)
 {
+	struct cx88_core *core = dev->core;
+
 	/* init struct videobuf_dvb */
-	dev->dvb.name = dev->core->name;
+	dev->dvb.name = core->name;
 	dev->ts_gen_cntrl = 0x0c;
 
 	/* init frontend */
-	switch (dev->core->boardnr) {
+	switch (core->boardnr) {
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 					       &connexant_refboard_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   &dev->core->i2c_adap,
-				   DVB_PLL_THOMSON_DTT759X);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, &core->i2c_adap,
+					DVB_PLL_THOMSON_DTT759X))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
@@ -545,11 +545,12 @@
 	case CX88_BOARD_WINFAST_DTV1000:
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 					       &connexant_refboard_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				   &dev->core->i2c_adap,
-				   DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x60, &core->i2c_adap,
+					DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_WINFAST_DTV2000H:
@@ -559,29 +560,32 @@
 	case CX88_BOARD_HAUPPAUGE_HVR3000:
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 					       &hauppauge_hvr_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_PHILIPS_FMD1216ME_MK3);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x61,
+				   TUNER_PHILIPS_FMD1216ME_MK3))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 			break;
 		}
 		/* ZL10353 replaces MT352 on later cards */
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_plus_v1_1,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
@@ -589,28 +593,31 @@
 		 * compatible, with a slightly different MT352 AGC gain. */
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv_dual,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 			break;
 		}
 		/* ZL10353 replaces MT352 on later cards */
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_plus_v1_1,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_LG_Z201);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_LG_Z201))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_KWORLD_DVB_T:
@@ -618,10 +625,11 @@
 	case CX88_BOARD_ADSTECH_DVB_T_PCI:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dntv_live_dvbt_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_UNKNOWN_1);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_UNKNOWN_1))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
@@ -630,32 +638,35 @@
 		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
 					       &dev->vp3054->adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_PHILIPS_FMD1216ME_MK3);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_PHILIPS_FMD1216ME_MK3))
+				goto frontend_detach;
 		}
 #else
-		printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name);
+		printk(KERN_ERR "%s/2: built without vp3054 support\n",
+				core->name);
 #endif
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_hybrid,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_THOMSON_FE6600);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x61,
+				   TUNER_THOMSON_FE6600))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_xc3028,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend == NULL)
 			dev->dvb.frontend = dvb_attach(mt352_attach,
 						&dvico_fusionhdtv_mt352_xc3028,
-						&dev->core->i2c_adap);
+						&core->i2c_adap);
 		/*
 		 * On this board, the demod provides the I2C bus pullup.
 		 * We must not permit gate_ctrl to be performed, or
@@ -668,19 +679,18 @@
 		break;
 	case CX88_BOARD_PCHDTV_HD3000:
 		dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_THOMSON_DTT761X);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_THOMSON_DTT761X))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
@@ -690,139 +700,137 @@
 		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_3_gold,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_MICROTUNE_4042FI5);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_MICROTUNE_4042FI5))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 9);
 		mdelay(200);
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_3_gold,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_THOMSON_DTT761X);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_THOMSON_DTT761X))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
 		mdelay(200);
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_5_gold,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_LG_TDVS_H06XF);
-			dvb_attach(tda9887_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x43);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_LG_TDVS_H06XF))
+				goto frontend_detach;
+			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x43))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_PCHDTV_HD5500:
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
 		mdelay(200);
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &pchdtv_hd5500,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_LG_TDVS_H06XF);
-			dvb_attach(tda9887_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x43);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_LG_TDVS_H06XF))
+				goto frontend_detach;
+			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x43))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_ATI_HDTVWONDER:
 		dev->dvb.frontend = dvb_attach(nxt200x_attach,
 					       &ati_hdtvwonder,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_PHILIPS_TUV1236D);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_PHILIPS_TUV1236D))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 					       &hauppauge_novas_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend) {
-			dvb_attach(isl6421_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x08, 0x00, 0x00);
+			if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x08, 0x00, 0x00))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_KWORLD_DVBS_100:
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 					       &kworld_dvbs_100_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend) {
-			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
 			dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
 		}
 		break;
 	case CX88_BOARD_GENIATECH_DVBS:
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 					       &geniatech_dvbs_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend) {
-			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
 			dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
 		}
 		break;
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 					       &pinnacle_pctv_hd_800i_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 			/* tuner_config.video_dev must point to
 			 * i2c_adap.algo_data
 			 */
-			pinnacle_pctv_hd_800i_tuner_config.priv =
-						dev->core->i2c_adap.algo_data;
-			dvb_attach(xc5000_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap,
-				   &pinnacle_pctv_hd_800i_tuner_config);
+			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+					&core->i2c_adap,
+					&pinnacle_pctv_hd_800i_tuner_config,
+					core->i2c_adap.algo_data))
+				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 						&dvico_hdtv5_pci_nano_config,
-						&dev->core->i2c_adap);
+						&core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 			struct dvb_frontend *fe;
 			struct xc2028_config cfg = {
-				.i2c_adap  = &dev->core->i2c_adap,
+				.i2c_adap  = &core->i2c_adap,
 				.i2c_addr  = 0x61,
 				.callback  = cx88_pci_nano_callback,
 			};
@@ -841,50 +849,50 @@
 	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &cx88_geniatech_x8000_mt,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
-			return -EINVAL;
+			goto frontend_detach;
 		break;
 	 case CX88_BOARD_GENIATECH_X8000_MT:
 		dev->ts_gen_cntrl = 0x00;
 
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &cx88_geniatech_x8000_mt,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
-			return -EINVAL;
+			goto frontend_detach;
 		break;
 	 case CX88_BOARD_KWORLD_ATSC_120:
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 					       &kworld_atsc_120_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
-			return -EINVAL;
+			goto frontend_detach;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
 		dev->dvb.frontend = dvb_attach(s5h1411_attach,
 					       &dvico_fusionhdtv7_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 			/* tuner_config.video_dev must point to
 			 * i2c_adap.algo_data
 			 */
-			dvico_fusionhdtv7_tuner_config.priv =
-						dev->core->i2c_adap.algo_data;
-			dvb_attach(xc5000_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap,
-				   &dvico_fusionhdtv7_tuner_config);
+			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+					&core->i2c_adap,
+					&dvico_fusionhdtv7_tuner_config,
+					core->i2c_adap.algo_data))
+				goto frontend_detach;
 		}
 		break;
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
-		       dev->core->name);
+		       core->name);
 		break;
 	}
 	if (NULL == dev->dvb.frontend) {
 		printk(KERN_ERR
 		       "%s/2: frontend initialization failed\n",
-		       dev->core->name);
+		       core->name);
 		return -EINVAL;
 	}
 
@@ -892,11 +900,18 @@
 	dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
 
 	/* Put the analog decoder in standby to keep it quiet */
-	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+	cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
 
 	/* register everything */
 	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
 				     &dev->pci->dev, adapter_nr);
+
+frontend_detach:
+	if (dev->dvb.frontend) {
+		dvb_frontend_detach(dev->dvb.frontend);
+		dev->dvb.frontend = NULL;
+	}
+	return -EINVAL;
 }
 
 /* ----------------------------------------------------------- */
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index c7c2896..16a5af3 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,7 +1,7 @@
 config VIDEO_EM28XX
 	tristate "Empia EM28xx USB video capture support"
 	depends on VIDEO_DEV && I2C && INPUT
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_IR
 	select VIDEOBUF_VMALLOC
@@ -35,7 +35,6 @@
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select VIDEOBUF_DVB
-	select FW_LOADER
 	---help---
 	  This adds support for DVB cards based on the
 	  Empiatech em28xx chips.
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 50ccf37..3e4f3c7 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -420,7 +420,13 @@
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
 	{ USB_DEVICE(0x2040, 0x6502),
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
-	{ USB_DEVICE(0x2040, 0x6513),
+	{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
+			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+	{ USB_DEVICE(0x2040, 0x6517), /* HP  HVR-950 */
+			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+	{ USB_DEVICE(0x2040, 0x651b), /* RP  HVR-950 */
+			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+	{ USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 	{ USB_DEVICE(0x0ccd, 0x0042),
 			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 7df81575..8cf4983 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -251,7 +251,6 @@
 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 		       dev->name);
 		dvb_frontend_detach(dev->dvb->frontend);
-		dvb_unregister_frontend(dev->dvb->frontend);
 		dev->dvb->frontend = NULL;
 		return -EINVAL;
 	}
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index eec115b..5d7ee8f 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -1,10 +1,12 @@
 config VIDEO_IVTV
 	tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
 	depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
+	depends on INPUT   # due to VIDEO_IR
+	depends on HOTPLUG # due to FW_LOADER
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_CX2341X
 	select VIDEO_CX25840
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 8c02fa6..c7e449f 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -181,12 +181,12 @@
 		return 0;
 	}
 	/* Need sliced data for mpeg insertion */
-	if (get_service_set(itv->vbi.sliced_in) == 0) {
+	if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) {
 		if (itv->is_60hz)
 			itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
 		else
 			itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
-		expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
+		ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
 	}
 	return 0;
 }
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index ed020f7..797e636 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -853,6 +853,7 @@
 	return 0;
 }
 
+#ifdef MODULE
 static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
 		const char *name, u32 id)
 {
@@ -865,12 +866,14 @@
 	IVTV_DEBUG_INFO("Loaded module %s\n", name);
 	return hw;
 }
+#endif
 
 static void ivtv_load_and_init_modules(struct ivtv *itv)
 {
 	u32 hw = itv->card->hw_all;
 	unsigned i;
 
+#ifdef MODULE
 	/* load modules */
 #ifndef CONFIG_MEDIA_TUNER
 	hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
@@ -911,6 +914,7 @@
 #ifndef CONFIG_VIDEO_M52790
 	hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
 #endif
+#endif
 
 	/* check which i2c devices are actually found */
 	for (i = 0; i < 32; i++) {
@@ -1228,7 +1232,7 @@
 	return 0;
 
 free_streams:
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 1);
 free_irq:
 	free_irq(itv->dev->irq, (void *)itv);
 free_i2c:
@@ -1373,7 +1377,7 @@
 	flush_workqueue(itv->irq_work_queues);
 	destroy_workqueue(itv->irq_work_queues);
 
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 1);
 	ivtv_udma_free(itv);
 
 	exit_ivtv_i2c(itv);
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 2b74b0a..f2fa434 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -987,6 +987,8 @@
 	/* Find which card this open was on */
 	spin_lock(&ivtv_cards_lock);
 	for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
+		if (ivtv_cards[x] == NULL)
+			continue;
 		/* find out which stream this open was on */
 		for (y = 0; y < IVTV_MAX_STREAMS; y++) {
 			s = &ivtv_cards[x]->streams[y];
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index d508b5d..26cc0f6 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -38,7 +38,7 @@
 #include <linux/dvb/audio.h>
 #include <linux/i2c-id.h>
 
-u16 service2vbi(int type)
+u16 ivtv_service2vbi(int type)
 {
 	switch (type) {
 		case V4L2_SLICED_TELETEXT_B:
@@ -88,7 +88,7 @@
 	return 0;
 }
 
-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 {
 	u16 set = fmt->service_set;
 	int f, l;
@@ -115,7 +115,7 @@
 	return set != 0;
 }
 
-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt)
+u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
 {
 	int f, l;
 	u16 set = 0;
@@ -466,7 +466,7 @@
 			vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
 			vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
 		}
-		vbifmt->service_set = get_service_set(vbifmt);
+		vbifmt->service_set = ivtv_get_service_set(vbifmt);
 		break;
 	}
 
@@ -481,12 +481,12 @@
 		if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
 			vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
 						 V4L2_SLICED_VBI_525;
-			expand_service_set(vbifmt, itv->is_50hz);
+			ivtv_expand_service_set(vbifmt, itv->is_50hz);
 			break;
 		}
 
 		itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
-		vbifmt->service_set = get_service_set(vbifmt);
+		vbifmt->service_set = ivtv_get_service_set(vbifmt);
 		break;
 	}
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
@@ -640,9 +640,9 @@
 	memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
 
 	if (vbifmt->service_set)
-		expand_service_set(vbifmt, itv->is_50hz);
+		ivtv_expand_service_set(vbifmt, itv->is_50hz);
 	set = check_service_set(vbifmt, itv->is_50hz);
-	vbifmt->service_set = get_service_set(vbifmt);
+	vbifmt->service_set = ivtv_get_service_set(vbifmt);
 
 	if (!set_fmt)
 		return 0;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
index a03351b..4e67f0e 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.h
+++ b/drivers/media/video/ivtv/ivtv-ioctl.h
@@ -21,9 +21,9 @@
 #ifndef IVTV_IOCTL_H
 #define IVTV_IOCTL_H
 
-u16 service2vbi(int type);
-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt);
+u16 ivtv_service2vbi(int type);
+void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
+u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
 int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 		    unsigned long arg);
 int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index 3e1deec..fc8b1ea 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -203,14 +203,14 @@
 		s->dma != PCI_DMA_NONE ? "DMA " : "",
 		s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
 
-	s->sg_pending = kzalloc(SGsize, GFP_KERNEL);
+	s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
 	if (s->sg_pending == NULL) {
 		IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
 		return -ENOMEM;
 	}
 	s->sg_pending_size = 0;
 
-	s->sg_processing = kzalloc(SGsize, GFP_KERNEL);
+	s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
 	if (s->sg_processing == NULL) {
 		IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
 		kfree(s->sg_pending);
@@ -219,7 +219,8 @@
 	}
 	s->sg_processing_size = 0;
 
-	s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), GFP_KERNEL);
+	s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element),
+					GFP_KERNEL|__GFP_NOWARN);
 	if (s->sg_dma == NULL) {
 		IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
 		kfree(s->sg_pending);
@@ -235,11 +236,12 @@
 
 	/* allocate stream buffers. Initially all buffers are in q_free. */
 	for (i = 0; i < s->buffers; i++) {
-		struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), GFP_KERNEL);
+		struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer),
+						GFP_KERNEL|__GFP_NOWARN);
 
 		if (buf == NULL)
 			break;
-		buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL);
+		buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN);
 		if (buf->buf == NULL) {
 			kfree(buf);
 			break;
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 4ab8d36..c47c2b9 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -244,7 +244,7 @@
 		return 0;
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 0);
 	return -ENOMEM;
 }
 
@@ -304,12 +304,12 @@
 		return 0;
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 1);
 	return -ENOMEM;
 }
 
 /* Unregister v4l2 devices */
-void ivtv_streams_cleanup(struct ivtv *itv)
+void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
 {
 	int type;
 
@@ -322,8 +322,11 @@
 			continue;
 
 		ivtv_stream_free(&itv->streams[type]);
-		/* Unregister device */
-		video_unregister_device(vdev);
+		/* Unregister or release device */
+		if (unregister)
+			video_unregister_device(vdev);
+		else
+			video_device_release(vdev);
 	}
 }
 
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
index 3d76a41..a653a51 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -23,7 +23,7 @@
 
 int ivtv_streams_setup(struct ivtv *itv);
 int ivtv_streams_register(struct ivtv *itv);
-void ivtv_streams_cleanup(struct ivtv *itv);
+void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
 
 /* Capture related */
 int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index c151bcf..71798f0 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -169,7 +169,8 @@
 			linemask[0] |= (1 << l);
 		else
 			linemask[1] |= (1 << (l - 32));
-		dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
+		dst[sd + 12 + line * 43] =
+			ivtv_service2vbi(itv->vbi.sliced_data[i].id);
 		memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
 		line++;
 	}
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 62f70bd..a9417f6 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -908,7 +908,7 @@
 	}
 
 	/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
-	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL);
+	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
 	if (yi->blanking_ptr) {
 		yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
 	} else {
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index df789f6..73be154 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -948,7 +948,8 @@
 	}
 
 	/* Allocate the pseudo palette */
-	oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
+	oi->ivtvfb_info.pseudo_palette =
+		kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
 
 	if (!oi->ivtvfb_info.pseudo_palette) {
 		IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
@@ -1056,7 +1057,8 @@
 		return -EBUSY;
 	}
 
-	itv->osd_info = kzalloc(sizeof(struct osd_info), GFP_ATOMIC);
+	itv->osd_info = kzalloc(sizeof(struct osd_info),
+					GFP_ATOMIC|__GFP_NOWARN);
 	if (itv->osd_info == NULL) {
 		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
 		return -ENOMEM;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 179e470..ee43499 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -12,15 +12,12 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
+#include <linux/gpio.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-#include <asm/gpio.h>
-#endif
-
 /* mt9m001 i2c address 0x5d
  * The platform has to define i2c_board_info
  * and call i2c_register_board_info() */
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index d1391ac..1658fe5 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -13,15 +13,12 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/gpio.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-#include <asm/gpio.h>
-#endif
-
 /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
  * The platform has to define i2c_board_info
  * and call i2c_register_board_info() */
@@ -91,7 +88,7 @@
 struct mt9v022 {
 	struct i2c_client *client;
 	struct soc_camera_device icd;
-	int model;	/* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
+	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
 	int switch_gpio;
 	u16 chip_control;
 	unsigned char datawidth;
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 9620c67..4482b2c 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -1,8 +1,10 @@
 config VIDEO_PVRUSB2
 	tristate "Hauppauge WinTV-PVR USB2 support"
 	depends on VIDEO_V4L2 && I2C
+	depends on VIDEO_MEDIA	# Avoids pvrusb = Y / DVB = M
+	depends on HOTPLUG	# due to FW_LOADER
 	select FW_LOADER
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_CX2341X
 	select VIDEO_SAA711X
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 40e4c3b..83f076a 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -3,7 +3,7 @@
 	depends on VIDEO_DEV && PCI && I2C && INPUT
 	select VIDEOBUF_DMA_SG
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select CRC32
 	---help---
@@ -27,6 +27,7 @@
 config VIDEO_SAA7134_DVB
 	tristate "DVB/ATSC Support for saa7134 based TV cards"
 	depends on VIDEO_SAA7134 && DVB_CORE
+	depends on HOTPLUG	# due to FW_LOADER
 	select VIDEOBUF_DVB
 	select FW_LOADER
 	select DVB_PLL if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index eec1278..2c19cd0 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -864,7 +864,6 @@
 	struct saa7134_dev *dev;
 	struct saa7134_mpeg_ops *mops;
 	int err;
-	int mask;
 
 	if (saa7134_devcount == SAA7134_MAXBOARDS)
 		return -ENOMEM;
@@ -1065,11 +1064,6 @@
 	if (TUNER_ABSENT != dev->tuner_type)
 		saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
 
-	if (card(dev).gpiomask != 0) {
-		mask = card(dev).gpiomask;
-		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   mask, mask);
-		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, 0);
-	}
 	return 0;
 
  fail4:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 2d16be2..469f93a 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -538,19 +538,23 @@
 	return 0;
 }
 
-static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *cdec_conf,
-							  struct tda827x_config *tuner_conf)
+static int configure_tda827x_fe(struct saa7134_dev *dev,
+				struct tda1004x_config *cdec_conf,
+				struct tda827x_config *tuner_conf)
 {
 	dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
 	if (dev->dvb.frontend) {
 		if (cdec_conf->i2c_gate)
 			dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
-		if (dvb_attach(tda827x_attach, dev->dvb.frontend, cdec_conf->tuner_address,
-							&dev->i2c_adap, tuner_conf) == NULL) {
-			wprintk("no tda827x tuner found at addr: %02x\n",
+		if (dvb_attach(tda827x_attach, dev->dvb.frontend,
+			       cdec_conf->tuner_address,
+			       &dev->i2c_adap, tuner_conf))
+			return 0;
+
+		wprintk("no tda827x tuner found at addr: %02x\n",
 				cdec_conf->tuner_address);
-		}
 	}
+	return -EINVAL;
 }
 
 /* ------------------------------------------------------------------ */
@@ -997,7 +1001,9 @@
 		break;
 	case SAA7134_BOARD_FLYDVBTDUO:
 	case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
-		configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_PHILIPS_EUROPA:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
@@ -1022,36 +1028,52 @@
 		}
 		break;
 	case SAA7134_BOARD_KWORLD_DVBT_210:
-		configure_tda827x_fe(dev, &kworld_dvb_t_210_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_PHILIPS_TIGER:
-		configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &philips_tiger_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
-		configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, &tda827x_cfg_1);
+		if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config,
+					 &tda827x_cfg_1) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
-		configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, &tda827x_cfg_1);
+		if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config,
+					 &tda827x_cfg_1) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
-		configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_FLYDVBT_LR301:
-		configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_FLYDVB_TRIO:
-		if(! use_frontend) {	/* terrestrial */
-			configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0);
+		if (!use_frontend) {	/* terrestrial */
+			if (configure_tda827x_fe(dev, &lifeview_trio_config,
+						 &tda827x_cfg_0) < 0)
+				goto dettach_frontend;
 		} else {  		/* satellite */
 			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
 			if (dev->dvb.frontend) {
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
 									&dev->i2c_adap, 0) == NULL) {
 					wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
+					goto dettach_frontend;
 				}
 				if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
 										0x08, 0, 0) == NULL) {
 					wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
+					goto dettach_frontend;
 				}
 			}
 		}
@@ -1067,15 +1089,20 @@
 								&ads_duo_cfg) == NULL) {
 				wprintk("no tda827x tuner found at addr: %02x\n",
 					ads_tech_duo_config.tuner_address);
+				goto dettach_frontend;
 			}
 		}
 		break;
 	case SAA7134_BOARD_TEVION_DVBT_220RF:
-		configure_tda827x_fe(dev, &tevion_dvbt220rf_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
 		if (!use_frontend) {     /* terrestrial */
-			configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
+			if (configure_tda827x_fe(dev, &md8800_dvbt_config,
+						 &tda827x_cfg_0) < 0)
+				goto dettach_frontend;
 		} else {        /* satellite */
 			dev->dvb.frontend = dvb_attach(tda10086_attach,
 							&flydvbs, &dev->i2c_adap);
@@ -1086,16 +1113,20 @@
 				struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
 
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend,
-						0x60, &dev->i2c_adap, 0) == NULL)
+						0x60, &dev->i2c_adap, 0) == NULL) {
 					wprintk("%s: Medion Quadro, no tda826x "
 						"found !\n", __func__);
+					goto dettach_frontend;
+				}
 				if (dev_id != 0x08) {
 					/* we need to open the i2c gate (we know it exists) */
 					fe->ops.i2c_gate_ctrl(fe, 1);
 					if (dvb_attach(isl6405_attach, fe,
-							&dev->i2c_adap, 0x08, 0, 0) == NULL)
+							&dev->i2c_adap, 0x08, 0, 0) == NULL) {
 						wprintk("%s: Medion Quadro, no ISL6405 "
 							"found !\n", __func__);
+						goto dettach_frontend;
+					}
 					if (dev_id == 0x07) {
 						/* fire up the 2nd section of the LNB supply since
 						   we can't do this from the other section */
@@ -1117,19 +1148,17 @@
 	case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
+		if (dev->dvb.frontend)
 			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
 				   NULL, DVB_PLL_TDHU2);
-		}
 		break;
 	case SAA7134_BOARD_KWORLD_ATSC110:
 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
+		if (dev->dvb.frontend)
 			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
 				   &dev->i2c_adap, 0x61,
 				   TUNER_PHILIPS_TUV1236D);
-		}
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
@@ -1138,10 +1167,12 @@
 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
 				       &dev->i2c_adap, 0) == NULL) {
 				wprintk("%s: No tda826x found!\n", __func__);
+				goto dettach_frontend;
 			}
 			if (dvb_attach(isl6421_attach, dev->dvb.frontend,
 				       &dev->i2c_adap, 0x08, 0, 0) == NULL) {
 				wprintk("%s: No ISL6421 found!\n", __func__);
+				goto dettach_frontend;
 			}
 		}
 		break;
@@ -1168,43 +1199,65 @@
 		}
 		break;
 	case SAA7134_BOARD_CINERGY_HT_PCMCIA:
-		configure_tda827x_fe(dev, &cinergy_ht_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &cinergy_ht_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_CINERGY_HT_PCI:
-		configure_tda827x_fe(dev, &cinergy_ht_pci_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &cinergy_ht_pci_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_PHILIPS_TIGER_S:
-		configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &philips_tiger_s_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_ASUS_P7131_4871:
-		configure_tda827x_fe(dev, &asus_p7131_4871_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &asus_p7131_4871_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
-		configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
-		configure_tda827x_fe(dev, &avermedia_super_007_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &avermedia_super_007_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
-		configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, &tda827x_cfg_2_sw42);
+		if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config,
+					 &tda827x_cfg_2_sw42) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_PHILIPS_SNAKE:
 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
 						&dev->i2c_adap);
 		if (dev->dvb.frontend) {
 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
-					&dev->i2c_adap, 0) == NULL)
+					&dev->i2c_adap, 0) == NULL) {
 				wprintk("%s: No tda826x found!\n", __func__);
+				goto dettach_frontend;
+			}
 			if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
-					&dev->i2c_adap, 0, 0) == NULL)
+					&dev->i2c_adap, 0, 0) == NULL) {
 				wprintk("%s: No lnbp21 found!\n", __func__);
+				goto dettach_frontend;
+			}
 		}
 		break;
 	case SAA7134_BOARD_CREATIX_CTX953:
-		configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &md8800_dvbt_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_MSI_TVANYWHERE_AD11:
-		configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &philips_tiger_s_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
@@ -1218,16 +1271,20 @@
 		if (dev->dvb.frontend) {
 			struct dvb_frontend *fe;
 			if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL)
+				  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
 				wprintk("%s: MD7134 DVB-S, no SD1878 "
 					"found !\n", __func__);
+				goto dettach_frontend;
+			}
 			/* we need to open the i2c gate (we know it exists) */
 			fe = dev->dvb.frontend;
 			fe->ops.i2c_gate_ctrl(fe, 1);
 			if (dvb_attach(isl6405_attach, fe,
-					&dev->i2c_adap, 0x08, 0, 0) == NULL)
+					&dev->i2c_adap, 0x08, 0, 0) == NULL) {
 				wprintk("%s: MD7134 DVB-S, no ISL6405 "
 					"found !\n", __func__);
+				goto dettach_frontend;
+			}
 			fe->ops.i2c_gate_ctrl(fe, 0);
 			dev->original_set_voltage = fe->ops.set_voltage;
 			fe->ops.set_voltage = md8800_set_voltage;
@@ -1254,10 +1311,7 @@
 		if (!fe) {
 			printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 			       dev->name);
-			dvb_frontend_detach(dev->dvb.frontend);
-			dvb_unregister_frontend(dev->dvb.frontend);
-			dev->dvb.frontend = NULL;
-			return -1;
+			goto dettach_frontend;
 		}
 	}
 
@@ -1282,6 +1336,12 @@
 			dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
 	}
 	return ret;
+
+dettach_frontend:
+	dvb_frontend_detach(dev->dvb.frontend);
+	dev->dvb.frontend = NULL;
+
+	return -1;
 }
 
 static int dvb_fini(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index a0baf2d..48e1a01 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1634,7 +1634,7 @@
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
 	int err;
-	unsigned int flags;
+	unsigned long flags;
 
 	if (saa7134_no_overlay > 0) {
 		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index 9276ed9..b12c60c 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -30,6 +30,7 @@
 #include <linux/kref.h>
 
 #include <linux/usb.h>
+#include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
@@ -245,6 +246,8 @@
 		return -1;
 }
 
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+
 /* sysfs functions */
 /*FIXME cleanup this */
 
@@ -350,6 +353,10 @@
 	video_device_remove_file(vdev, &dev_attr_vflip);
 }
 
+#else
+#define stk_create_sysfs_files(a)
+#define stk_remove_sysfs_files(a)
+#endif
 
 /* *********************************************** */
 /*
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index e57a646..8f0100f 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -885,12 +885,19 @@
 	return 0;
 }
 
+static const struct i2c_device_id tcm825x_id[] = {
+	{ "tcm825x", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tcm825x_id);
+
 static struct i2c_driver tcm825x_i2c_driver = {
 	.driver	= {
 		.name = TCM825X_NAME,
 	},
 	.probe	= tcm825x_probe,
 	.remove	= __exit_p(tcm825x_remove),
+	.id_table = tcm825x_id,
 };
 
 static struct tcm825x_sensor tcm825x = {
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index f1db542..28ab9f9 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -168,6 +168,11 @@
 
 /* ----------------------------------------------------------------------- */
 
+static const struct i2c_device_id tlv320aic23b_id[] = {
+	{ "tlv320aic23b", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tlv320aic23b",
@@ -175,4 +180,5 @@
 	.command = tlv320aic23b_command,
 	.probe = tlv320aic23b_probe,
 	.remove = tlv320aic23b_remove,
+	.id_table = tlv320aic23b_id,
 };
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 6bf104e..5a75788 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -40,11 +40,11 @@
 	typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
 	if (__a) { \
 		__r = (int) __a(ARGS); \
+		symbol_put(FUNCTION); \
 	} else { \
 		printk(KERN_ERR "TUNER: Unable to find " \
 				"symbol "#FUNCTION"()\n"); \
 	} \
-	symbol_put(FUNCTION); \
 	__r; \
 })
 
@@ -340,16 +340,6 @@
 	tuner_warn("====================== WARNING! ======================\n");
 }
 
-static void attach_tda829x(struct tuner *t)
-{
-	struct tda829x_config cfg = {
-		.lna_cfg        = t->config,
-		.tuner_callback = t->tuner_callback,
-	};
-	dvb_attach(tda829x_attach,
-		   &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
-}
-
 static struct xc5000_config xc5000_cfg;
 
 static void set_type(struct i2c_client *c, unsigned int type,
@@ -385,12 +375,19 @@
 
 	switch (t->type) {
 	case TUNER_MT2032:
-		dvb_attach(microtune_attach,
-			   &t->fe, t->i2c->adapter, t->i2c->addr);
+		if (!dvb_attach(microtune_attach,
+			   &t->fe, t->i2c->adapter, t->i2c->addr))
+			goto attach_failed;
 		break;
 	case TUNER_PHILIPS_TDA8290:
 	{
-		attach_tda829x(t);
+		struct tda829x_config cfg = {
+			.lna_cfg        = t->config,
+			.tuner_callback = t->tuner_callback,
+		};
+		if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter,
+				t->i2c->addr, &cfg))
+			goto attach_failed;
 		break;
 	}
 	case TUNER_TEA5767:
@@ -441,8 +438,9 @@
 		break;
 	}
 	case TUNER_TDA9887:
-		dvb_attach(tda9887_attach,
-			   &t->fe, t->i2c->adapter, t->i2c->addr);
+		if (!dvb_attach(tda9887_attach,
+			   &t->fe, t->i2c->adapter, t->i2c->addr))
+			goto attach_failed;
 		break;
 	case TUNER_XC5000:
 	{
@@ -450,10 +448,10 @@
 
 		xc5000_cfg.i2c_address	  = t->i2c->addr;
 		xc5000_cfg.if_khz	  = 5380;
-		xc5000_cfg.priv           = c->adapter->algo_data;
 		xc5000_cfg.tuner_callback = t->tuner_callback;
 		if (!dvb_attach(xc5000_attach,
-				&t->fe, t->i2c->adapter, &xc5000_cfg))
+				&t->fe, t->i2c->adapter, &xc5000_cfg,
+				c->adapter->algo_data))
 			goto attach_failed;
 
 		xc_tuner_ops = &t->fe.ops.tuner_ops;
@@ -1167,7 +1165,7 @@
 			/* If chip is not tda8290, don't register.
 			   since it can be tda9887*/
 			if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
-					       t->i2c->addr) == 0) {
+					       t->i2c->addr) >= 0) {
 				tuner_dbg("tda829x detected\n");
 			} else {
 				/* Default is being tda9887 */
@@ -1181,7 +1179,7 @@
 		case 0x60:
 			if (tuner_symbol_probe(tea5767_autodetection,
 					       t->i2c->adapter, t->i2c->addr)
-					!= EINVAL) {
+					>= 0) {
 				t->type = TUNER_TEA5767;
 				t->mode_mask = T_RADIO;
 				t->mode = T_STANDBY;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 6f9945b..c77914d 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -1505,7 +1505,8 @@
 	}
 
 	/* fill required data structures */
-	strcpy(client->name, desc->name);
+	if (!id)
+		strlcpy(client->name, desc->name, I2C_NAME_SIZE);
 	chip->type = desc-chiplist;
 	chip->shadow.count = desc->registers+1;
 	chip->prevmode = -1;
@@ -1830,6 +1831,15 @@
 	return 0;
 }
 
+/* This driver supports many devices and the idea is to let the driver
+   detect which device is present. So rather than listing all supported
+   devices here, we pretend to support a single, fake device type. */
+static const struct i2c_device_id chip_id[] = {
+	{ "tvaudio", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, chip_id);
+
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tvaudio",
 	.driverid = I2C_DRIVERID_TVAUDIO,
@@ -1837,6 +1847,7 @@
 	.probe = chip_probe,
 	.remove = chip_remove,
 	.legacy_probe = chip_legacy_probe,
+	.id_table = chip_id,
 };
 
 /*
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3cf8a8e..9da0e18 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -319,10 +319,12 @@
 	{AUDIO_CHIP_INTERNAL, "CX25843"},
 	{AUDIO_CHIP_INTERNAL, "CX23418"},
 	{AUDIO_CHIP_INTERNAL, "CX23885"},
-	/* 40-42 */
+	/* 40-44 */
 	{AUDIO_CHIP_INTERNAL, "CX23888"},
 	{AUDIO_CHIP_INTERNAL, "SAA7131"},
 	{AUDIO_CHIP_INTERNAL, "CX23887"},
+	{AUDIO_CHIP_INTERNAL, "SAA7164"},
+	{AUDIO_CHIP_INTERNAL, "AU8522"},
 };
 
 /* This list is supplied by Hauppauge. Thanks! */
@@ -341,8 +343,10 @@
 	"CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
 	/* 30-34 */
 	"CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
-	/* 35-37 */
-	"SAA7131", "CX25837", "CX23887"
+	/* 35-39 */
+	"SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
+	/* 40-42 */
+	"SAA7164", "CX23885B", "AU8522"
 };
 
 static int hasRadioTuner(int tunerType)
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig
index 74e1d30..fc24ef0 100644
--- a/drivers/media/video/usbvision/Kconfig
+++ b/drivers/media/video/usbvision/Kconfig
@@ -1,7 +1,7 @@
 config VIDEO_USBVISION
 	tristate "USB video devices based on Nogatech NT1003/1004/1005"
 	depends on I2C && VIDEO_V4L2
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
 	---help---
 	  There are more than 50 different USB video devices based on
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c
index 30a1af8..fa39410 100644
--- a/drivers/misc/kgdbts.c
+++ b/drivers/misc/kgdbts.c
@@ -47,6 +47,7 @@
  *       to test the HW NMI watchdog
  * F## = Break at do_fork for ## iterations
  * S## = Break at sys_open for ## iterations
+ * I## = Run the single step test ## iterations
  *
  * NOTE: that the do_fork and sys_open tests are mutually exclusive.
  *
@@ -375,7 +376,7 @@
 		break;
 	case 1:
 		/* set breakpoint */
-		break_helper("Z0", 0, sstep_addr);
+		break_helper("Z0", NULL, sstep_addr);
 		break;
 	case 2:
 		/* Continue */
@@ -383,7 +384,7 @@
 		break;
 	case 3:
 		/* Clear breakpoint */
-		break_helper("z0", 0, sstep_addr);
+		break_helper("z0", NULL, sstep_addr);
 		break;
 	default:
 		eprintk("kgdbts: ERROR failed sstep get emulation\n");
@@ -465,11 +466,11 @@
 	{ "?", "S0*" }, /* Clear break points */
 	{ "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
 	{ "c", "T0*", }, /* Continue */
-	{ "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+	{ "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
 	{ "write", "OK", write_regs },
 	{ "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
 	{ "D", "OK" }, /* Detach */
-	{ "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+	{ "D", "OK", NULL,  got_break }, /* On success we made it here */
 	{ "", "" },
 };
 
@@ -499,14 +500,14 @@
 	{ "?", "S0*" }, /* Clear break points */
 	{ "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
 	{ "c", "T0*", }, /* Continue */
-	{ "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+	{ "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
 	{ "write", "OK", write_regs }, /* Write registers */
 	{ "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
 	{ "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
-	{ "g", "kgdbts_break_test", 0, check_single_step },
+	{ "g", "kgdbts_break_test", NULL, check_single_step },
 	{ "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
 	{ "c", "T0*", }, /* Continue */
-	{ "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+	{ "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
 	{ "write", "OK", write_regs }, /* Write registers */
 	{ "D", "OK" }, /* Remove all breakpoints and continues */
 	{ "", "" },
@@ -520,14 +521,14 @@
 	{ "?", "S0*" }, /* Clear break points */
 	{ "do_fork", "OK", sw_break, }, /* set sw breakpoint */
 	{ "c", "T0*", }, /* Continue */
-	{ "g", "do_fork", 0, check_and_rewind_pc }, /* check location */
+	{ "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */
 	{ "write", "OK", write_regs }, /* Write registers */
 	{ "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
 	{ "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
-	{ "g", "do_fork", 0, check_single_step },
+	{ "g", "do_fork", NULL, check_single_step },
 	{ "do_fork", "OK", sw_break, }, /* set sw breakpoint */
 	{ "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
-	{ "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */
+	{ "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
 	{ "", "" },
 };
 
@@ -538,14 +539,14 @@
 	{ "?", "S0*" }, /* Clear break points */
 	{ "sys_open", "OK", sw_break, }, /* set sw breakpoint */
 	{ "c", "T0*", }, /* Continue */
-	{ "g", "sys_open", 0, check_and_rewind_pc }, /* check location */
+	{ "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */
 	{ "write", "OK", write_regs }, /* Write registers */
 	{ "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
 	{ "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
-	{ "g", "sys_open", 0, check_single_step },
+	{ "g", "sys_open", NULL, check_single_step },
 	{ "sys_open", "OK", sw_break, }, /* set sw breakpoint */
 	{ "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
-	{ "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */
+	{ "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
 	{ "", "" },
 };
 
@@ -556,11 +557,11 @@
 	{ "?", "S0*" }, /* Clear break points */
 	{ "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */
 	{ "c", "T0*", }, /* Continue */
-	{ "g", "kgdbts_break_test", 0, check_and_rewind_pc },
+	{ "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
 	{ "write", "OK", write_regs },
 	{ "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */
 	{ "D", "OK" }, /* Detach */
-	{ "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+	{ "D", "OK", NULL,  got_break }, /* On success we made it here */
 	{ "", "" },
 };
 
@@ -570,12 +571,12 @@
 static struct test_struct hw_write_break_test[] = {
 	{ "?", "S0*" }, /* Clear break points */
 	{ "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */
-	{ "c", "T0*", 0, got_break }, /* Continue */
-	{ "g", "silent", 0, check_and_rewind_pc },
+	{ "c", "T0*", NULL, got_break }, /* Continue */
+	{ "g", "silent", NULL, check_and_rewind_pc },
 	{ "write", "OK", write_regs },
 	{ "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */
 	{ "D", "OK" }, /* Detach */
-	{ "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+	{ "D", "OK", NULL,  got_break }, /* On success we made it here */
 	{ "", "" },
 };
 
@@ -585,12 +586,12 @@
 static struct test_struct hw_access_break_test[] = {
 	{ "?", "S0*" }, /* Clear break points */
 	{ "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */
-	{ "c", "T0*", 0, got_break }, /* Continue */
-	{ "g", "silent", 0, check_and_rewind_pc },
+	{ "c", "T0*", NULL, got_break }, /* Continue */
+	{ "g", "silent", NULL, check_and_rewind_pc },
 	{ "write", "OK", write_regs },
 	{ "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */
 	{ "D", "OK" }, /* Detach */
-	{ "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+	{ "D", "OK", NULL,  got_break }, /* On success we made it here */
 	{ "", "" },
 };
 
@@ -599,9 +600,9 @@
  */
 static struct test_struct nmi_sleep_test[] = {
 	{ "?", "S0*" }, /* Clear break points */
-	{ "c", "T0*", 0, got_break }, /* Continue */
+	{ "c", "T0*", NULL, got_break }, /* Continue */
 	{ "D", "OK" }, /* Detach */
-	{ "D", "OK", 0,  got_break }, /* If the test worked we made it here */
+	{ "D", "OK", NULL,  got_break }, /* On success we made it here */
 	{ "", "" },
 };
 
@@ -874,18 +875,23 @@
 {
 	char *ptr;
 	int fork_test = 0;
-	int sys_open_test = 0;
+	int do_sys_open_test = 0;
+	int sstep_test = 1000;
 	int nmi_sleep = 0;
+	int i;
 
 	ptr = strstr(config, "F");
 	if (ptr)
-		fork_test = simple_strtol(ptr+1, NULL, 10);
+		fork_test = simple_strtol(ptr + 1, NULL, 10);
 	ptr = strstr(config, "S");
 	if (ptr)
-		sys_open_test = simple_strtol(ptr+1, NULL, 10);
+		do_sys_open_test = simple_strtol(ptr + 1, NULL, 10);
 	ptr = strstr(config, "N");
 	if (ptr)
 		nmi_sleep = simple_strtol(ptr+1, NULL, 10);
+	ptr = strstr(config, "I");
+	if (ptr)
+		sstep_test = simple_strtol(ptr+1, NULL, 10);
 
 	/* required internal KGDB tests */
 	v1printk("kgdbts:RUN plant and detach test\n");
@@ -894,8 +900,13 @@
 	run_breakpoint_test(0);
 	v1printk("kgdbts:RUN bad memory access test\n");
 	run_bad_read_test();
-	v1printk("kgdbts:RUN singlestep breakpoint test\n");
-	run_singlestep_break_test();
+	v1printk("kgdbts:RUN singlestep test %i iterations\n", sstep_test);
+	for (i = 0; i < sstep_test; i++) {
+		run_singlestep_break_test();
+		if (i % 100 == 0)
+			v1printk("kgdbts:RUN singlestep [%i/%i]\n",
+				 i, sstep_test);
+	}
 
 	/* ===Optional tests=== */
 
@@ -922,7 +933,7 @@
 		repeat_test = fork_test;
 		printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n",
 			repeat_test);
-		kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg");
+		kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg");
 		run_do_fork_test();
 		return;
 	}
@@ -931,11 +942,11 @@
 	 * executed because a kernel thread will be spawned at the very
 	 * end to unregister the debug hooks.
 	 */
-	if (sys_open_test) {
-		repeat_test = sys_open_test;
+	if (do_sys_open_test) {
+		repeat_test = do_sys_open_test;
 		printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n",
 			repeat_test);
-		kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg");
+		kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg");
 		run_sys_open_test();
 		return;
 	}
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h
index 5515234..03a87a3 100644
--- a/drivers/misc/sgi-xp/xp.h
+++ b/drivers/misc/sgi-xp/xp.h
@@ -157,215 +157,136 @@
 /*
  * Define the return values and values passed to user's callout functions.
  * (It is important to add new value codes at the end just preceding
- * xpcUnknownReason, which must have the highest numerical value.)
+ * xpUnknownReason, which must have the highest numerical value.)
  */
-enum xpc_retval {
-	xpcSuccess = 0,
+enum xp_retval {
+	xpSuccess = 0,
 
-	xpcNotConnected,	/*  1: channel is not connected */
-	xpcConnected,		/*  2: channel connected (opened) */
-	xpcRETIRED1,		/*  3: (formerly xpcDisconnected) */
+	xpNotConnected,		/*  1: channel is not connected */
+	xpConnected,		/*  2: channel connected (opened) */
+	xpRETIRED1,		/*  3: (formerly xpDisconnected) */
 
-	xpcMsgReceived,		/*  4: message received */
-	xpcMsgDelivered,	/*  5: message delivered and acknowledged */
+	xpMsgReceived,		/*  4: message received */
+	xpMsgDelivered,		/*  5: message delivered and acknowledged */
 
-	xpcRETIRED2,		/*  6: (formerly xpcTransferFailed) */
+	xpRETIRED2,		/*  6: (formerly xpTransferFailed) */
 
-	xpcNoWait,		/*  7: operation would require wait */
-	xpcRetry,		/*  8: retry operation */
-	xpcTimeout,		/*  9: timeout in xpc_allocate_msg_wait() */
-	xpcInterrupted,		/* 10: interrupted wait */
+	xpNoWait,		/*  7: operation would require wait */
+	xpRetry,		/*  8: retry operation */
+	xpTimeout,		/*  9: timeout in xpc_allocate_msg_wait() */
+	xpInterrupted,		/* 10: interrupted wait */
 
-	xpcUnequalMsgSizes,	/* 11: message size disparity between sides */
-	xpcInvalidAddress,	/* 12: invalid address */
+	xpUnequalMsgSizes,	/* 11: message size disparity between sides */
+	xpInvalidAddress,	/* 12: invalid address */
 
-	xpcNoMemory,		/* 13: no memory available for XPC structures */
-	xpcLackOfResources,	/* 14: insufficient resources for operation */
-	xpcUnregistered,	/* 15: channel is not registered */
-	xpcAlreadyRegistered,	/* 16: channel is already registered */
+	xpNoMemory,		/* 13: no memory available for XPC structures */
+	xpLackOfResources,	/* 14: insufficient resources for operation */
+	xpUnregistered,		/* 15: channel is not registered */
+	xpAlreadyRegistered,	/* 16: channel is already registered */
 
-	xpcPartitionDown,	/* 17: remote partition is down */
-	xpcNotLoaded,		/* 18: XPC module is not loaded */
-	xpcUnloading,		/* 19: this side is unloading XPC module */
+	xpPartitionDown,	/* 17: remote partition is down */
+	xpNotLoaded,		/* 18: XPC module is not loaded */
+	xpUnloading,		/* 19: this side is unloading XPC module */
 
-	xpcBadMagic,		/* 20: XPC MAGIC string not found */
+	xpBadMagic,		/* 20: XPC MAGIC string not found */
 
-	xpcReactivating,	/* 21: remote partition was reactivated */
+	xpReactivating,		/* 21: remote partition was reactivated */
 
-	xpcUnregistering,	/* 22: this side is unregistering channel */
-	xpcOtherUnregistering,	/* 23: other side is unregistering channel */
+	xpUnregistering,	/* 22: this side is unregistering channel */
+	xpOtherUnregistering,	/* 23: other side is unregistering channel */
 
-	xpcCloneKThread,	/* 24: cloning kernel thread */
-	xpcCloneKThreadFailed,	/* 25: cloning kernel thread failed */
+	xpCloneKThread,		/* 24: cloning kernel thread */
+	xpCloneKThreadFailed,	/* 25: cloning kernel thread failed */
 
-	xpcNoHeartbeat,		/* 26: remote partition has no heartbeat */
+	xpNoHeartbeat,		/* 26: remote partition has no heartbeat */
 
-	xpcPioReadError,	/* 27: PIO read error */
-	xpcPhysAddrRegFailed,	/* 28: registration of phys addr range failed */
+	xpPioReadError,		/* 27: PIO read error */
+	xpPhysAddrRegFailed,	/* 28: registration of phys addr range failed */
 
-	xpcBteDirectoryError,	/* 29: maps to BTEFAIL_DIR */
-	xpcBtePoisonError,	/* 30: maps to BTEFAIL_POISON */
-	xpcBteWriteError,	/* 31: maps to BTEFAIL_WERR */
-	xpcBteAccessError,	/* 32: maps to BTEFAIL_ACCESS */
-	xpcBtePWriteError,	/* 33: maps to BTEFAIL_PWERR */
-	xpcBtePReadError,	/* 34: maps to BTEFAIL_PRERR */
-	xpcBteTimeOutError,	/* 35: maps to BTEFAIL_TOUT */
-	xpcBteXtalkError,	/* 36: maps to BTEFAIL_XTERR */
-	xpcBteNotAvailable,	/* 37: maps to BTEFAIL_NOTAVAIL */
-	xpcBteUnmappedError,	/* 38: unmapped BTEFAIL_ error */
+	xpRETIRED3,		/* 29: (formerly xpBteDirectoryError) */
+	xpRETIRED4,		/* 30: (formerly xpBtePoisonError) */
+	xpRETIRED5,		/* 31: (formerly xpBteWriteError) */
+	xpRETIRED6,		/* 32: (formerly xpBteAccessError) */
+	xpRETIRED7,		/* 33: (formerly xpBtePWriteError) */
+	xpRETIRED8,		/* 34: (formerly xpBtePReadError) */
+	xpRETIRED9,		/* 35: (formerly xpBteTimeOutError) */
+	xpRETIRED10,		/* 36: (formerly xpBteXtalkError) */
+	xpRETIRED11,		/* 37: (formerly xpBteNotAvailable) */
+	xpRETIRED12,		/* 38: (formerly xpBteUnmappedError) */
 
-	xpcBadVersion,		/* 39: bad version number */
-	xpcVarsNotSet,		/* 40: the XPC variables are not set up */
-	xpcNoRsvdPageAddr,	/* 41: unable to get rsvd page's phys addr */
-	xpcInvalidPartid,	/* 42: invalid partition ID */
-	xpcLocalPartid,		/* 43: local partition ID */
+	xpBadVersion,		/* 39: bad version number */
+	xpVarsNotSet,		/* 40: the XPC variables are not set up */
+	xpNoRsvdPageAddr,	/* 41: unable to get rsvd page's phys addr */
+	xpInvalidPartid,	/* 42: invalid partition ID */
+	xpLocalPartid,		/* 43: local partition ID */
 
-	xpcOtherGoingDown,	/* 44: other side going down, reason unknown */
-	xpcSystemGoingDown,	/* 45: system is going down, reason unknown */
-	xpcSystemHalt,		/* 46: system is being halted */
-	xpcSystemReboot,	/* 47: system is being rebooted */
-	xpcSystemPoweroff,	/* 48: system is being powered off */
+	xpOtherGoingDown,	/* 44: other side going down, reason unknown */
+	xpSystemGoingDown,	/* 45: system is going down, reason unknown */
+	xpSystemHalt,		/* 46: system is being halted */
+	xpSystemReboot,		/* 47: system is being rebooted */
+	xpSystemPoweroff,	/* 48: system is being powered off */
 
-	xpcDisconnecting,	/* 49: channel disconnecting (closing) */
+	xpDisconnecting,	/* 49: channel disconnecting (closing) */
 
-	xpcOpenCloseError,	/* 50: channel open/close protocol error */
+	xpOpenCloseError,	/* 50: channel open/close protocol error */
 
-	xpcDisconnected,	/* 51: channel disconnected (closed) */
+	xpDisconnected,		/* 51: channel disconnected (closed) */
 
-	xpcBteSh2Start,		/* 52: BTE CRB timeout */
+	xpBteCopyError,		/* 52: bte_copy() returned error */
 
-				/* 53: 0x1 BTE Error Response Short */
-	xpcBteSh2RspShort = xpcBteSh2Start + BTEFAIL_SH2_RESP_SHORT,
-
-				/* 54: 0x2 BTE Error Response Long */
-	xpcBteSh2RspLong = xpcBteSh2Start + BTEFAIL_SH2_RESP_LONG,
-
-				/* 56: 0x4 BTE Error Response DSB */
-	xpcBteSh2RspDSB = xpcBteSh2Start + BTEFAIL_SH2_RESP_DSP,
-
-				/* 60: 0x8 BTE Error Response Access */
-	xpcBteSh2RspAccess = xpcBteSh2Start + BTEFAIL_SH2_RESP_ACCESS,
-
-				/* 68: 0x10 BTE Error CRB timeout */
-	xpcBteSh2CRBTO = xpcBteSh2Start + BTEFAIL_SH2_CRB_TO,
-
-				/* 84: 0x20 BTE Error NACK limit */
-	xpcBteSh2NACKLimit = xpcBteSh2Start + BTEFAIL_SH2_NACK_LIMIT,
-
-				/* 115: BTE end */
-	xpcBteSh2End = xpcBteSh2Start + BTEFAIL_SH2_ALL,
-
-	xpcUnknownReason	/* 116: unknown reason - must be last in enum */
+	xpUnknownReason		/* 53: unknown reason - must be last in enum */
 };
 
 /*
- * Define the callout function types used by XPC to update the user on
- * connection activity and state changes (via the user function registered by
- * xpc_connect()) and to notify them of messages received and delivered (via
- * the user function registered by xpc_send_notify()).
- *
- * The two function types are xpc_channel_func and xpc_notify_func and
- * both share the following arguments, with the exception of "data", which
- * only xpc_channel_func has.
+ * Define the callout function type used by XPC to update the user on
+ * connection activity and state changes via the user function registered
+ * by xpc_connect().
  *
  * Arguments:
  *
- *	reason - reason code. (See following table.)
+ *	reason - reason code.
  *	partid - partition ID associated with condition.
  *	ch_number - channel # associated with condition.
- *	data - pointer to optional data. (See following table.)
+ *	data - pointer to optional data.
  *	key - pointer to optional user-defined value provided as the "key"
- *	      argument to xpc_connect() or xpc_send_notify().
+ *	      argument to xpc_connect().
  *
- * In the following table the "Optional Data" column applies to callouts made
- * to functions registered by xpc_connect(). A "NA" in that column indicates
- * that this reason code can be passed to functions registered by
- * xpc_send_notify() (i.e. they don't have data arguments).
+ * A reason code of xpConnected indicates that a connection has been
+ * established to the specified partition on the specified channel. The data
+ * argument indicates the max number of entries allowed in the message queue.
  *
- * Also, the first three reason codes in the following table indicate
- * success, whereas the others indicate failure. When a failure reason code
- * is received, one can assume that the channel is not connected.
+ * A reason code of xpMsgReceived indicates that a XPC message arrived from
+ * the specified partition on the specified channel. The data argument
+ * specifies the address of the message's payload. The user must call
+ * xpc_received() when finished with the payload.
  *
- *
- * Reason Code          | Cause                          | Optional Data
- * =====================+================================+=====================
- * xpcConnected         | connection has been established| max #of entries
- *                      | to the specified partition on  | allowed in message
- *                      | the specified channel          | queue
- * ---------------------+--------------------------------+---------------------
- * xpcMsgReceived       | an XPC message arrived from    | address of payload
- *                      | the specified partition on the |
- *                      | specified channel              | [the user must call
- *                      |                                | xpc_received() when
- *                      |                                | finished with the
- *                      |                                | payload]
- * ---------------------+--------------------------------+---------------------
- * xpcMsgDelivered      | notification that the message  | NA
- *                      | was delivered to the intended  |
- *                      | recipient and that they have   |
- *                      | acknowledged its receipt by    |
- *                      | calling xpc_received()         |
- * =====================+================================+=====================
- * xpcUnequalMsgSizes   | can't connect to the specified | NULL
- *                      | partition on the specified     |
- *                      | channel because of mismatched  |
- *                      | message sizes                  |
- * ---------------------+--------------------------------+---------------------
- * xpcNoMemory          | insufficient memory avaiable   | NULL
- *                      | to allocate message queue      |
- * ---------------------+--------------------------------+---------------------
- * xpcLackOfResources   | lack of resources to create    | NULL
- *                      | the necessary kthreads to      |
- *                      | support the channel            |
- * ---------------------+--------------------------------+---------------------
- * xpcUnregistering     | this side's user has           | NULL or NA
- *                      | unregistered by calling        |
- *                      | xpc_disconnect()               |
- * ---------------------+--------------------------------+---------------------
- * xpcOtherUnregistering| the other side's user has      | NULL or NA
- *                      | unregistered by calling        |
- *                      | xpc_disconnect()               |
- * ---------------------+--------------------------------+---------------------
- * xpcNoHeartbeat       | the other side's XPC is no     | NULL or NA
- *                      | longer heartbeating            |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcUnloading         | this side's XPC module is      | NULL or NA
- *                      | being unloaded                 |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcOtherUnloading    | the other side's XPC module is | NULL or NA
- *                      | is being unloaded              |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcPioReadError      | xp_nofault_PIOR() returned an  | NULL or NA
- *                      | error while sending an IPI     |
- *                      |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcInvalidAddress    | the address either received or | NULL or NA
- *                      | sent by the specified partition|
- *                      | is invalid                     |
- * ---------------------+--------------------------------+---------------------
- * xpcBteNotAvailable   | attempt to pull data from the  | NULL or NA
- * xpcBtePoisonError    | specified partition over the   |
- * xpcBteWriteError     | specified channel via a        |
- * xpcBteAccessError    | bte_copy() failed              |
- * xpcBteTimeOutError   |                                |
- * xpcBteXtalkError     |                                |
- * xpcBteDirectoryError |                                |
- * xpcBteGenericError   |                                |
- * xpcBteUnmappedError  |                                |
- * ---------------------+--------------------------------+---------------------
- * xpcUnknownReason     | the specified channel to the   | NULL or NA
- *                      | specified partition was        |
- *                      | unavailable for unknown reasons|
- * =====================+================================+=====================
+ * All other reason codes indicate failure. The data argmument is NULL.
+ * When a failure reason code is received, one can assume that the channel
+ * is not connected.
  */
-
-typedef void (*xpc_channel_func) (enum xpc_retval reason, partid_t partid,
+typedef void (*xpc_channel_func) (enum xp_retval reason, short partid,
 				  int ch_number, void *data, void *key);
 
-typedef void (*xpc_notify_func) (enum xpc_retval reason, partid_t partid,
+/*
+ * Define the callout function type used by XPC to notify the user of
+ * messages received and delivered via the user function registered by
+ * xpc_send_notify().
+ *
+ * Arguments:
+ *
+ *	reason - reason code.
+ *	partid - partition ID associated with condition.
+ *	ch_number - channel # associated with condition.
+ *	key - pointer to optional user-defined value provided as the "key"
+ *	      argument to xpc_send_notify().
+ *
+ * A reason code of xpMsgDelivered indicates that the message was delivered
+ * to the intended recipient and that they have acknowledged its receipt by
+ * calling xpc_received().
+ *
+ * All other reason codes indicate failure.
+ */
+typedef void (*xpc_notify_func) (enum xp_retval reason, short partid,
 				 int ch_number, void *key);
 
 /*
@@ -401,57 +322,57 @@
 struct xpc_interface {
 	void (*connect) (int);
 	void (*disconnect) (int);
-	enum xpc_retval (*allocate) (partid_t, int, u32, void **);
-	enum xpc_retval (*send) (partid_t, int, void *);
-	enum xpc_retval (*send_notify) (partid_t, int, void *,
+	enum xp_retval (*allocate) (short, int, u32, void **);
+	enum xp_retval (*send) (short, int, void *);
+	enum xp_retval (*send_notify) (short, int, void *,
 					xpc_notify_func, void *);
-	void (*received) (partid_t, int, void *);
-	enum xpc_retval (*partid_to_nasids) (partid_t, void *);
+	void (*received) (short, int, void *);
+	enum xp_retval (*partid_to_nasids) (short, void *);
 };
 
 extern struct xpc_interface xpc_interface;
 
 extern void xpc_set_interface(void (*)(int),
 			      void (*)(int),
-			      enum xpc_retval (*)(partid_t, int, u32, void **),
-			      enum xpc_retval (*)(partid_t, int, void *),
-			      enum xpc_retval (*)(partid_t, int, void *,
+			      enum xp_retval (*)(short, int, u32, void **),
+			      enum xp_retval (*)(short, int, void *),
+			      enum xp_retval (*)(short, int, void *,
 						  xpc_notify_func, void *),
-			      void (*)(partid_t, int, void *),
-			      enum xpc_retval (*)(partid_t, void *));
+			      void (*)(short, int, void *),
+			      enum xp_retval (*)(short, void *));
 extern void xpc_clear_interface(void);
 
-extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16,
+extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
 				   u16, u32, u32);
 extern void xpc_disconnect(int);
 
-static inline enum xpc_retval
-xpc_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
+static inline enum xp_retval
+xpc_allocate(short partid, int ch_number, u32 flags, void **payload)
 {
 	return xpc_interface.allocate(partid, ch_number, flags, payload);
 }
 
-static inline enum xpc_retval
-xpc_send(partid_t partid, int ch_number, void *payload)
+static inline enum xp_retval
+xpc_send(short partid, int ch_number, void *payload)
 {
 	return xpc_interface.send(partid, ch_number, payload);
 }
 
-static inline enum xpc_retval
-xpc_send_notify(partid_t partid, int ch_number, void *payload,
+static inline enum xp_retval
+xpc_send_notify(short partid, int ch_number, void *payload,
 		xpc_notify_func func, void *key)
 {
 	return xpc_interface.send_notify(partid, ch_number, payload, func, key);
 }
 
 static inline void
-xpc_received(partid_t partid, int ch_number, void *payload)
+xpc_received(short partid, int ch_number, void *payload)
 {
 	return xpc_interface.received(partid, ch_number, payload);
 }
 
-static inline enum xpc_retval
-xpc_partid_to_nasids(partid_t partid, void *nasids)
+static inline enum xp_retval
+xpc_partid_to_nasids(short partid, void *nasids)
 {
 	return xpc_interface.partid_to_nasids(partid, nasids);
 }
diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c
index 1fbf99b..196480b 100644
--- a/drivers/misc/sgi-xp/xp_main.c
+++ b/drivers/misc/sgi-xp/xp_main.c
@@ -42,21 +42,21 @@
 /*
  * Initialize the XPC interface to indicate that XPC isn't loaded.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_notloaded(void)
 {
-	return xpcNotLoaded;
+	return xpNotLoaded;
 }
 
 struct xpc_interface xpc_interface = {
 	(void (*)(int))xpc_notloaded,
 	(void (*)(int))xpc_notloaded,
-	(enum xpc_retval(*)(partid_t, int, u32, void **))xpc_notloaded,
-	(enum xpc_retval(*)(partid_t, int, void *))xpc_notloaded,
-	(enum xpc_retval(*)(partid_t, int, void *, xpc_notify_func, void *))
+	(enum xp_retval(*)(short, int, u32, void **))xpc_notloaded,
+	(enum xp_retval(*)(short, int, void *))xpc_notloaded,
+	(enum xp_retval(*)(short, int, void *, xpc_notify_func, void *))
 	    xpc_notloaded,
-	(void (*)(partid_t, int, void *))xpc_notloaded,
-	(enum xpc_retval(*)(partid_t, void *))xpc_notloaded
+	(void (*)(short, int, void *))xpc_notloaded,
+	(enum xp_retval(*)(short, void *))xpc_notloaded
 };
 EXPORT_SYMBOL_GPL(xpc_interface);
 
@@ -66,12 +66,12 @@
 void
 xpc_set_interface(void (*connect) (int),
 		  void (*disconnect) (int),
-		  enum xpc_retval (*allocate) (partid_t, int, u32, void **),
-		  enum xpc_retval (*send) (partid_t, int, void *),
-		  enum xpc_retval (*send_notify) (partid_t, int, void *,
+		  enum xp_retval (*allocate) (short, int, u32, void **),
+		  enum xp_retval (*send) (short, int, void *),
+		  enum xp_retval (*send_notify) (short, int, void *,
 						  xpc_notify_func, void *),
-		  void (*received) (partid_t, int, void *),
-		  enum xpc_retval (*partid_to_nasids) (partid_t, void *))
+		  void (*received) (short, int, void *),
+		  enum xp_retval (*partid_to_nasids) (short, void *))
 {
 	xpc_interface.connect = connect;
 	xpc_interface.disconnect = disconnect;
@@ -91,16 +91,16 @@
 {
 	xpc_interface.connect = (void (*)(int))xpc_notloaded;
 	xpc_interface.disconnect = (void (*)(int))xpc_notloaded;
-	xpc_interface.allocate = (enum xpc_retval(*)(partid_t, int, u32,
+	xpc_interface.allocate = (enum xp_retval(*)(short, int, u32,
 						     void **))xpc_notloaded;
-	xpc_interface.send = (enum xpc_retval(*)(partid_t, int, void *))
+	xpc_interface.send = (enum xp_retval(*)(short, int, void *))
 	    xpc_notloaded;
-	xpc_interface.send_notify = (enum xpc_retval(*)(partid_t, int, void *,
+	xpc_interface.send_notify = (enum xp_retval(*)(short, int, void *,
 							xpc_notify_func,
 							void *))xpc_notloaded;
-	xpc_interface.received = (void (*)(partid_t, int, void *))
+	xpc_interface.received = (void (*)(short, int, void *))
 	    xpc_notloaded;
-	xpc_interface.partid_to_nasids = (enum xpc_retval(*)(partid_t, void *))
+	xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *))
 	    xpc_notloaded;
 }
 EXPORT_SYMBOL_GPL(xpc_clear_interface);
@@ -123,13 +123,13 @@
  *	nentries - max #of XPC message entries a message queue can contain.
  *		   The actual number, which is determined when a connection
  * 		   is established and may be less then requested, will be
- *		   passed to the user via the xpcConnected callout.
+ *		   passed to the user via the xpConnected callout.
  *	assigned_limit - max number of kthreads allowed to be processing
  * 			 messages (per connection) at any given instant.
  *	idle_limit - max number of kthreads allowed to be idle at any given
  * 		     instant.
  */
-enum xpc_retval
+enum xp_retval
 xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
 	    u16 nentries, u32 assigned_limit, u32 idle_limit)
 {
@@ -143,12 +143,12 @@
 	registration = &xpc_registrations[ch_number];
 
 	if (mutex_lock_interruptible(&registration->mutex) != 0)
-		return xpcInterrupted;
+		return xpInterrupted;
 
 	/* if XPC_CHANNEL_REGISTERED(ch_number) */
 	if (registration->func != NULL) {
 		mutex_unlock(&registration->mutex);
-		return xpcAlreadyRegistered;
+		return xpAlreadyRegistered;
 	}
 
 	/* register the channel for connection */
@@ -163,7 +163,7 @@
 
 	xpc_interface.connect(ch_number);
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 EXPORT_SYMBOL_GPL(xpc_connect);
 
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 9eb6d4a..11ac267 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -172,13 +172,13 @@
 			(_version >= _XPC_VERSION(3, 1))
 
 static inline int
-xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
+xpc_hb_allowed(short partid, struct xpc_vars *vars)
 {
 	return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
 }
 
 static inline void
-xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
+xpc_allow_hb(short partid, struct xpc_vars *vars)
 {
 	u64 old_mask, new_mask;
 
@@ -190,7 +190,7 @@
 }
 
 static inline void
-xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
+xpc_disallow_hb(short partid, struct xpc_vars *vars)
 {
 	u64 old_mask, new_mask;
 
@@ -408,11 +408,11 @@
  *	messages.
  */
 struct xpc_channel {
-	partid_t partid;	/* ID of remote partition connected */
+	short partid;		/* ID of remote partition connected */
 	spinlock_t lock;	/* lock for updating this structure */
 	u32 flags;		/* general flags */
 
-	enum xpc_retval reason;	/* reason why channel is disconnect'g */
+	enum xp_retval reason;	/* reason why channel is disconnect'g */
 	int reason_line;	/* line# disconnect initiated from */
 
 	u16 number;		/* channel # */
@@ -522,7 +522,7 @@
 	spinlock_t act_lock;	/* protect updating of act_state */
 	u8 act_state;		/* from XPC HB viewpoint */
 	u8 remote_vars_version;	/* version# of partition's vars */
-	enum xpc_retval reason;	/* reason partition is deactivating */
+	enum xp_retval reason;	/* reason partition is deactivating */
 	int reason_line;	/* line# deactivation initiated from */
 	int reactivate_nasid;	/* nasid in partition to reactivate */
 
@@ -615,7 +615,7 @@
 /* interval in seconds to print 'waiting disengagement' messages */
 #define XPC_DISENGAGE_PRINTMSG_INTERVAL		10
 
-#define XPC_PARTID(_p)	((partid_t) ((_p) - &xpc_partitions[0]))
+#define XPC_PARTID(_p)	((short)((_p) - &xpc_partitions[0]))
 
 /* found in xp_main.c */
 extern struct xpc_registration xpc_registrations[];
@@ -646,31 +646,31 @@
 extern void xpc_restrict_IPI_ops(void);
 extern int xpc_identify_act_IRQ_sender(void);
 extern int xpc_partition_disengaged(struct xpc_partition *);
-extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *);
+extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
 extern void xpc_mark_partition_inactive(struct xpc_partition *);
 extern void xpc_discovery(void);
 extern void xpc_check_remote_hb(void);
 extern void xpc_deactivate_partition(const int, struct xpc_partition *,
-				     enum xpc_retval);
-extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
+				     enum xp_retval);
+extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
 
 /* found in xpc_channel.c */
 extern void xpc_initiate_connect(int);
 extern void xpc_initiate_disconnect(int);
-extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **);
-extern enum xpc_retval xpc_initiate_send(partid_t, int, void *);
-extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *,
-						xpc_notify_func, void *);
-extern void xpc_initiate_received(partid_t, int, void *);
-extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *);
-extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *);
+extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
+extern enum xp_retval xpc_initiate_send(short, int, void *);
+extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
+					       xpc_notify_func, void *);
+extern void xpc_initiate_received(short, int, void *);
+extern enum xp_retval xpc_setup_infrastructure(struct xpc_partition *);
+extern enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *);
 extern void xpc_process_channel_activity(struct xpc_partition *);
 extern void xpc_connected_callout(struct xpc_channel *);
 extern void xpc_deliver_msg(struct xpc_channel *);
 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
-				   enum xpc_retval, unsigned long *);
-extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval);
-extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
+				   enum xp_retval, unsigned long *);
+extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
+extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
 extern void xpc_teardown_infrastructure(struct xpc_partition *);
 
 static inline void
@@ -901,7 +901,7 @@
 	return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
 }
 
-static inline enum xpc_retval
+static inline enum xp_retval
 xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
 {
 	int ret = 0;
@@ -923,7 +923,7 @@
 
 	local_irq_restore(irq_flags);
 
-	return ((ret == 0) ? xpcSuccess : xpcPioReadError);
+	return ((ret == 0) ? xpSuccess : xpPioReadError);
 }
 
 /*
@@ -992,7 +992,7 @@
 		    unsigned long *irq_flags)
 {
 	struct xpc_partition *part = &xpc_partitions[ch->partid];
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	if (likely(part->act_state != XPC_P_DEACTIVATING)) {
 		ret = xpc_IPI_send(part->remote_IPI_amo_va,
@@ -1001,7 +1001,7 @@
 				   part->remote_IPI_phys_cpuid, SGI_XPC_NOTIFY);
 		dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
 			ipi_flag_string, ch->partid, ch->number, ret);
-		if (unlikely(ret != xpcSuccess)) {
+		if (unlikely(ret != xpSuccess)) {
 			if (irq_flags != NULL)
 				spin_unlock_irqrestore(&ch->lock, *irq_flags);
 			XPC_DEACTIVATE_PARTITION(part, ret);
@@ -1123,41 +1123,10 @@
 	return amo;
 }
 
-static inline enum xpc_retval
+static inline enum xp_retval
 xpc_map_bte_errors(bte_result_t error)
 {
-	if (error == BTE_SUCCESS)
-		return xpcSuccess;
-
-	if (is_shub2()) {
-		if (BTE_VALID_SH2_ERROR(error))
-			return xpcBteSh2Start + error;
-		return xpcBteUnmappedError;
-	}
-	switch (error) {
-	case BTE_SUCCESS:
-		return xpcSuccess;
-	case BTEFAIL_DIR:
-		return xpcBteDirectoryError;
-	case BTEFAIL_POISON:
-		return xpcBtePoisonError;
-	case BTEFAIL_WERR:
-		return xpcBteWriteError;
-	case BTEFAIL_ACCESS:
-		return xpcBteAccessError;
-	case BTEFAIL_PWERR:
-		return xpcBtePWriteError;
-	case BTEFAIL_PRERR:
-		return xpcBtePReadError;
-	case BTEFAIL_TOUT:
-		return xpcBteTimeOutError;
-	case BTEFAIL_XTERR:
-		return xpcBteXtalkError;
-	case BTEFAIL_NOTAVAIL:
-		return xpcBteNotAvailable;
-	default:
-		return xpcBteUnmappedError;
-	}
+	return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError);
 }
 
 /*
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index bfcb9ea..9c90c2d 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -53,7 +53,7 @@
  * Set up the initial values for the XPartition Communication channels.
  */
 static void
-xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
+xpc_initialize_channels(struct xpc_partition *part, short partid)
 {
 	int ch_number;
 	struct xpc_channel *ch;
@@ -90,12 +90,12 @@
  * Setup the infrastructure necessary to support XPartition Communication
  * between the specified remote partition and the local one.
  */
-enum xpc_retval
+enum xp_retval
 xpc_setup_infrastructure(struct xpc_partition *part)
 {
 	int ret, cpuid;
 	struct timer_list *timer;
-	partid_t partid = XPC_PARTID(part);
+	short partid = XPC_PARTID(part);
 
 	/*
 	 * Zero out MOST of the entry for this partition. Only the fields
@@ -114,7 +114,7 @@
 				 GFP_KERNEL);
 	if (part->channels == NULL) {
 		dev_err(xpc_chan, "can't get memory for channels\n");
-		return xpcNoMemory;
+		return xpNoMemory;
 	}
 
 	part->nchannels = XPC_NCHANNELS;
@@ -129,7 +129,7 @@
 		part->channels = NULL;
 		dev_err(xpc_chan, "can't get memory for local get/put "
 			"values\n");
-		return xpcNoMemory;
+		return xpNoMemory;
 	}
 
 	part->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
@@ -143,7 +143,7 @@
 		part->local_GPs = NULL;
 		kfree(part->channels);
 		part->channels = NULL;
-		return xpcNoMemory;
+		return xpNoMemory;
 	}
 
 	/* allocate all the required open and close args */
@@ -159,7 +159,7 @@
 		part->local_GPs = NULL;
 		kfree(part->channels);
 		part->channels = NULL;
-		return xpcNoMemory;
+		return xpNoMemory;
 	}
 
 	part->remote_openclose_args =
@@ -175,7 +175,7 @@
 		part->local_GPs = NULL;
 		kfree(part->channels);
 		part->channels = NULL;
-		return xpcNoMemory;
+		return xpNoMemory;
 	}
 
 	xpc_initialize_channels(part, partid);
@@ -209,7 +209,7 @@
 		part->local_GPs = NULL;
 		kfree(part->channels);
 		part->channels = NULL;
-		return xpcLackOfResources;
+		return xpLackOfResources;
 	}
 
 	/* Setup a timer to check for dropped IPIs */
@@ -243,7 +243,7 @@
 	xpc_vars_part[partid].nchannels = part->nchannels;
 	xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 
 /*
@@ -254,7 +254,7 @@
  * dst must be a cacheline aligned virtual address on this partition.
  * cnt must be an cacheline sized
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
 			   const void *src, size_t cnt)
 {
@@ -270,7 +270,7 @@
 	bte_ret = xp_bte_copy((u64)src, (u64)dst, (u64)cnt,
 			      (BTE_NORMAL | BTE_WACQUIRE), NULL);
 	if (bte_ret == BTE_SUCCESS)
-		return xpcSuccess;
+		return xpSuccess;
 
 	dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n",
 		XPC_PARTID(part), bte_ret);
@@ -282,7 +282,7 @@
  * Pull the remote per partition specific variables from the specified
  * partition.
  */
-enum xpc_retval
+enum xp_retval
 xpc_pull_remote_vars_part(struct xpc_partition *part)
 {
 	u8 buffer[L1_CACHE_BYTES * 2];
@@ -290,8 +290,8 @@
 	    (struct xpc_vars_part *)L1_CACHE_ALIGN((u64)buffer);
 	struct xpc_vars_part *pulled_entry;
 	u64 remote_entry_cacheline_pa, remote_entry_pa;
-	partid_t partid = XPC_PARTID(part);
-	enum xpc_retval ret;
+	short partid = XPC_PARTID(part);
+	enum xp_retval ret;
 
 	/* pull the cacheline that contains the variables we're interested in */
 
@@ -311,7 +311,7 @@
 	ret = xpc_pull_remote_cachelines(part, pulled_entry_cacheline,
 					 (void *)remote_entry_cacheline_pa,
 					 L1_CACHE_BYTES);
-	if (ret != xpcSuccess) {
+	if (ret != xpSuccess) {
 		dev_dbg(xpc_chan, "failed to pull XPC vars_part from "
 			"partition %d, ret=%d\n", partid, ret);
 		return ret;
@@ -326,11 +326,11 @@
 			dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
 				"partition %d has bad magic value (=0x%lx)\n",
 				partid, sn_partition_id, pulled_entry->magic);
-			return xpcBadMagic;
+			return xpBadMagic;
 		}
 
 		/* they've not been initialized yet */
-		return xpcRetry;
+		return xpRetry;
 	}
 
 	if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) {
@@ -344,7 +344,7 @@
 			dev_err(xpc_chan, "partition %d's XPC vars_part for "
 				"partition %d are not valid\n", partid,
 				sn_partition_id);
-			return xpcInvalidAddress;
+			return xpInvalidAddress;
 		}
 
 		/* the variables we imported look to be valid */
@@ -366,9 +366,9 @@
 	}
 
 	if (pulled_entry->magic == XPC_VP_MAGIC1)
-		return xpcRetry;
+		return xpRetry;
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 
 /*
@@ -379,7 +379,7 @@
 {
 	unsigned long irq_flags;
 	u64 IPI_amo;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	/*
 	 * See if there are any IPI flags to be handled.
@@ -398,7 +398,7 @@
 						 (void *)part->
 						 remote_openclose_args_pa,
 						 XPC_OPENCLOSE_ARGS_SIZE);
-		if (ret != xpcSuccess) {
+		if (ret != xpSuccess) {
 			XPC_DEACTIVATE_PARTITION(part, ret);
 
 			dev_dbg(xpc_chan, "failed to pull openclose args from "
@@ -414,7 +414,7 @@
 		ret = xpc_pull_remote_cachelines(part, part->remote_GPs,
 						 (void *)part->remote_GPs_pa,
 						 XPC_GP_SIZE);
-		if (ret != xpcSuccess) {
+		if (ret != xpSuccess) {
 			XPC_DEACTIVATE_PARTITION(part, ret);
 
 			dev_dbg(xpc_chan, "failed to pull GPs from partition "
@@ -431,7 +431,7 @@
 /*
  * Allocate the local message queue and the notify queue.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_local_msgqueue(struct xpc_channel *ch)
 {
 	unsigned long irq_flags;
@@ -464,18 +464,18 @@
 			ch->local_nentries = nentries;
 		}
 		spin_unlock_irqrestore(&ch->lock, irq_flags);
-		return xpcSuccess;
+		return xpSuccess;
 	}
 
 	dev_dbg(xpc_chan, "can't get memory for local message queue and notify "
 		"queue, partid=%d, channel=%d\n", ch->partid, ch->number);
-	return xpcNoMemory;
+	return xpNoMemory;
 }
 
 /*
  * Allocate the cached remote message queue.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
 {
 	unsigned long irq_flags;
@@ -502,12 +502,12 @@
 			ch->remote_nentries = nentries;
 		}
 		spin_unlock_irqrestore(&ch->lock, irq_flags);
-		return xpcSuccess;
+		return xpSuccess;
 	}
 
 	dev_dbg(xpc_chan, "can't get memory for cached remote message queue, "
 		"partid=%d, channel=%d\n", ch->partid, ch->number);
-	return xpcNoMemory;
+	return xpNoMemory;
 }
 
 /*
@@ -515,20 +515,20 @@
  *
  * Note: Assumes all of the channel sizes are filled in.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_msgqueues(struct xpc_channel *ch)
 {
 	unsigned long irq_flags;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	DBUG_ON(ch->flags & XPC_C_SETUP);
 
 	ret = xpc_allocate_local_msgqueue(ch);
-	if (ret != xpcSuccess)
+	if (ret != xpSuccess)
 		return ret;
 
 	ret = xpc_allocate_remote_msgqueue(ch);
-	if (ret != xpcSuccess) {
+	if (ret != xpSuccess) {
 		kfree(ch->local_msgqueue_base);
 		ch->local_msgqueue = NULL;
 		kfree(ch->notify_queue);
@@ -540,7 +540,7 @@
 	ch->flags |= XPC_C_SETUP;
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 
 /*
@@ -552,7 +552,7 @@
 static void
 xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
 {
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	DBUG_ON(!spin_is_locked(&ch->lock));
 
@@ -568,7 +568,7 @@
 		ret = xpc_allocate_msgqueues(ch);
 		spin_lock_irqsave(&ch->lock, *irq_flags);
 
-		if (ret != xpcSuccess)
+		if (ret != xpSuccess)
 			XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
 
 		if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
@@ -603,7 +603,7 @@
  * Notify those who wanted to be notified upon delivery of their message.
  */
 static void
-xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put)
+xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put)
 {
 	struct xpc_notify *notify;
 	u8 notify_type;
@@ -748,7 +748,7 @@
 
 	if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
 		spin_unlock_irqrestore(&ch->lock, *irq_flags);
-		xpc_disconnect_callout(ch, xpcDisconnected);
+		xpc_disconnect_callout(ch, xpDisconnected);
 		spin_lock_irqsave(&ch->lock, *irq_flags);
 	}
 
@@ -791,7 +791,7 @@
 	struct xpc_openclose_args *args =
 	    &part->remote_openclose_args[ch_number];
 	struct xpc_channel *ch = &part->channels[ch_number];
-	enum xpc_retval reason;
+	enum xp_retval reason;
 
 	spin_lock_irqsave(&ch->lock, irq_flags);
 
@@ -871,10 +871,10 @@
 
 		if (!(ch->flags & XPC_C_DISCONNECTING)) {
 			reason = args->reason;
-			if (reason <= xpcSuccess || reason > xpcUnknownReason)
-				reason = xpcUnknownReason;
-			else if (reason == xpcUnregistering)
-				reason = xpcOtherUnregistering;
+			if (reason <= xpSuccess || reason > xpUnknownReason)
+				reason = xpUnknownReason;
+			else if (reason == xpUnregistering)
+				reason = xpOtherUnregistering;
 
 			XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
 
@@ -961,7 +961,7 @@
 
 		if (ch->flags & XPC_C_OPENREQUEST) {
 			if (args->msg_size != ch->msg_size) {
-				XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
+				XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
 						       &irq_flags);
 				spin_unlock_irqrestore(&ch->lock, irq_flags);
 				return;
@@ -991,7 +991,7 @@
 			return;
 		}
 		if (!(ch->flags & XPC_C_OPENREQUEST)) {
-			XPC_DISCONNECT_CHANNEL(ch, xpcOpenCloseError,
+			XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
 					       &irq_flags);
 			spin_unlock_irqrestore(&ch->lock, irq_flags);
 			return;
@@ -1042,18 +1042,18 @@
 /*
  * Attempt to establish a channel connection to a remote partition.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_connect_channel(struct xpc_channel *ch)
 {
 	unsigned long irq_flags;
 	struct xpc_registration *registration = &xpc_registrations[ch->number];
 
 	if (mutex_trylock(&registration->mutex) == 0)
-		return xpcRetry;
+		return xpRetry;
 
 	if (!XPC_CHANNEL_REGISTERED(ch->number)) {
 		mutex_unlock(&registration->mutex);
-		return xpcUnregistered;
+		return xpUnregistered;
 	}
 
 	spin_lock_irqsave(&ch->lock, irq_flags);
@@ -1095,10 +1095,10 @@
 			 * the channel lock as needed.
 			 */
 			mutex_unlock(&registration->mutex);
-			XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
+			XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
 					       &irq_flags);
 			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return xpcUnequalMsgSizes;
+			return xpUnequalMsgSizes;
 		}
 	} else {
 		ch->msg_size = registration->msg_size;
@@ -1120,7 +1120,7 @@
 
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 
 /*
@@ -1203,7 +1203,7 @@
 			 * Notify senders that messages sent have been
 			 * received and delivered by the other side.
 			 */
-			xpc_notify_senders(ch, xpcMsgDelivered,
+			xpc_notify_senders(ch, xpMsgDelivered,
 					   ch->remote_GP.get);
 		}
 
@@ -1335,7 +1335,7 @@
  * at the same time.
  */
 void
-xpc_partition_going_down(struct xpc_partition *part, enum xpc_retval reason)
+xpc_partition_going_down(struct xpc_partition *part, enum xp_retval reason)
 {
 	unsigned long irq_flags;
 	int ch_number;
@@ -1375,7 +1375,7 @@
 void
 xpc_teardown_infrastructure(struct xpc_partition *part)
 {
-	partid_t partid = XPC_PARTID(part);
+	short partid = XPC_PARTID(part);
 
 	/*
 	 * We start off by making this partition inaccessible to local
@@ -1428,7 +1428,7 @@
 void
 xpc_initiate_connect(int ch_number)
 {
-	partid_t partid;
+	short partid;
 	struct xpc_partition *part;
 	struct xpc_channel *ch;
 
@@ -1456,13 +1456,13 @@
 	/* let the registerer know that a connection has been established */
 
 	if (ch->func != NULL) {
-		dev_dbg(xpc_chan, "ch->func() called, reason=xpcConnected, "
+		dev_dbg(xpc_chan, "ch->func() called, reason=xpConnected, "
 			"partid=%d, channel=%d\n", ch->partid, ch->number);
 
-		ch->func(xpcConnected, ch->partid, ch->number,
+		ch->func(xpConnected, ch->partid, ch->number,
 			 (void *)(u64)ch->local_nentries, ch->key);
 
-		dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, "
+		dev_dbg(xpc_chan, "ch->func() returned, reason=xpConnected, "
 			"partid=%d, channel=%d\n", ch->partid, ch->number);
 	}
 }
@@ -1484,7 +1484,7 @@
 xpc_initiate_disconnect(int ch_number)
 {
 	unsigned long irq_flags;
-	partid_t partid;
+	short partid;
 	struct xpc_partition *part;
 	struct xpc_channel *ch;
 
@@ -1503,7 +1503,7 @@
 			if (!(ch->flags & XPC_C_DISCONNECTED)) {
 				ch->flags |= XPC_C_WDISCONNECT;
 
-				XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering,
+				XPC_DISCONNECT_CHANNEL(ch, xpUnregistering,
 						       &irq_flags);
 			}
 
@@ -1528,7 +1528,7 @@
  */
 void
 xpc_disconnect_channel(const int line, struct xpc_channel *ch,
-		       enum xpc_retval reason, unsigned long *irq_flags)
+		       enum xp_retval reason, unsigned long *irq_flags)
 {
 	u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED);
 
@@ -1563,7 +1563,7 @@
 
 	} else if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
 		   !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
-		/* start a kthread that will do the xpcDisconnecting callout */
+		/* start a kthread that will do the xpDisconnecting callout */
 		xpc_create_kthreads(ch, 1, 1);
 	}
 
@@ -1575,7 +1575,7 @@
 }
 
 void
-xpc_disconnect_callout(struct xpc_channel *ch, enum xpc_retval reason)
+xpc_disconnect_callout(struct xpc_channel *ch, enum xp_retval reason)
 {
 	/*
 	 * Let the channel's registerer know that the channel is being
@@ -1598,13 +1598,13 @@
  * Wait for a message entry to become available for the specified channel,
  * but don't wait any longer than 1 jiffy.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_msg_wait(struct xpc_channel *ch)
 {
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	if (ch->flags & XPC_C_DISCONNECTING) {
-		DBUG_ON(ch->reason == xpcInterrupted);
+		DBUG_ON(ch->reason == xpInterrupted);
 		return ch->reason;
 	}
 
@@ -1614,11 +1614,11 @@
 
 	if (ch->flags & XPC_C_DISCONNECTING) {
 		ret = ch->reason;
-		DBUG_ON(ch->reason == xpcInterrupted);
+		DBUG_ON(ch->reason == xpInterrupted);
 	} else if (ret == 0) {
-		ret = xpcTimeout;
+		ret = xpTimeout;
 	} else {
-		ret = xpcInterrupted;
+		ret = xpInterrupted;
 	}
 
 	return ret;
@@ -1628,12 +1628,12 @@
  * Allocate an entry for a message from the message queue associated with the
  * specified channel.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_allocate_msg(struct xpc_channel *ch, u32 flags,
 		 struct xpc_msg **address_of_msg)
 {
 	struct xpc_msg *msg;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 	s64 put;
 
 	/* this reference will be dropped in xpc_send_msg() */
@@ -1645,7 +1645,7 @@
 	}
 	if (!(ch->flags & XPC_C_CONNECTED)) {
 		xpc_msgqueue_deref(ch);
-		return xpcNotConnected;
+		return xpNotConnected;
 	}
 
 	/*
@@ -1653,7 +1653,7 @@
 	 * If none are available, we'll make sure that we grab the latest
 	 * GP values.
 	 */
-	ret = xpcTimeout;
+	ret = xpTimeout;
 
 	while (1) {
 
@@ -1683,16 +1683,16 @@
 		 * that will cause the IPI handler to fetch the latest
 		 * GP values as if an IPI was sent by the other side.
 		 */
-		if (ret == xpcTimeout)
+		if (ret == xpTimeout)
 			xpc_IPI_send_local_msgrequest(ch);
 
 		if (flags & XPC_NOWAIT) {
 			xpc_msgqueue_deref(ch);
-			return xpcNoWait;
+			return xpNoWait;
 		}
 
 		ret = xpc_allocate_msg_wait(ch);
-		if (ret != xpcInterrupted && ret != xpcTimeout) {
+		if (ret != xpInterrupted && ret != xpTimeout) {
 			xpc_msgqueue_deref(ch);
 			return ret;
 		}
@@ -1711,7 +1711,7 @@
 
 	*address_of_msg = msg;
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 
 /*
@@ -1727,11 +1727,11 @@
  *	payload - address of the allocated payload area pointer (filled in on
  * 	          return) in which the user-defined message is constructed.
  */
-enum xpc_retval
-xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
+enum xp_retval
+xpc_initiate_allocate(short partid, int ch_number, u32 flags, void **payload)
 {
 	struct xpc_partition *part = &xpc_partitions[partid];
-	enum xpc_retval ret = xpcUnknownReason;
+	enum xp_retval ret = xpUnknownReason;
 	struct xpc_msg *msg = NULL;
 
 	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
@@ -1814,11 +1814,11 @@
  * local message queue's Put value and sends an IPI to the partition the
  * message is being sent to.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
 	     xpc_notify_func func, void *key)
 {
-	enum xpc_retval ret = xpcSuccess;
+	enum xp_retval ret = xpSuccess;
 	struct xpc_notify *notify = notify;
 	s64 put, msg_number = msg->number;
 
@@ -1908,12 +1908,12 @@
  *	payload - pointer to the payload area allocated via
  *			xpc_initiate_allocate().
  */
-enum xpc_retval
-xpc_initiate_send(partid_t partid, int ch_number, void *payload)
+enum xp_retval
+xpc_initiate_send(short partid, int ch_number, void *payload)
 {
 	struct xpc_partition *part = &xpc_partitions[partid];
 	struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
 		partid, ch_number);
@@ -1957,13 +1957,13 @@
  *		  receipt. THIS FUNCTION MUST BE NON-BLOCKING.
  *	key - user-defined key to be passed to the function when it's called.
  */
-enum xpc_retval
-xpc_initiate_send_notify(partid_t partid, int ch_number, void *payload,
+enum xp_retval
+xpc_initiate_send_notify(short partid, int ch_number, void *payload,
 			 xpc_notify_func func, void *key)
 {
 	struct xpc_partition *part = &xpc_partitions[partid];
 	struct xpc_msg *msg = XPC_MSG_ADDRESS(payload);
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg,
 		partid, ch_number);
@@ -1985,7 +1985,7 @@
 	struct xpc_msg *remote_msg, *msg;
 	u32 msg_index, nmsgs;
 	u64 msg_offset;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
 		/* we were interrupted by a signal */
@@ -2012,7 +2012,7 @@
 
 		ret = xpc_pull_remote_cachelines(part, msg, remote_msg,
 						 nmsgs * ch->msg_size);
-		if (ret != xpcSuccess) {
+		if (ret != xpSuccess) {
 
 			dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
 				" msg %ld from partition %d, channel=%d, "
@@ -2112,7 +2112,7 @@
 				ch->number);
 
 			/* deliver the message to its intended recipient */
-			ch->func(xpcMsgReceived, ch->partid, ch->number,
+			ch->func(xpMsgReceived, ch->partid, ch->number,
 				 &msg->payload, ch->key);
 
 			dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, "
@@ -2203,7 +2203,7 @@
  *			xpc_initiate_allocate().
  */
 void
-xpc_initiate_received(partid_t partid, int ch_number, void *payload)
+xpc_initiate_received(short partid, int ch_number, void *payload)
 {
 	struct xpc_partition *part = &xpc_partitions[partid];
 	struct xpc_channel *ch;
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index f673ba9..08256ed 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -315,13 +315,13 @@
  * the XPC per partition variables from the remote partition and waiting for
  * the remote partition to pull ours.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_make_first_contact(struct xpc_partition *part)
 {
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
-	while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) {
-		if (ret != xpcRetry) {
+	while ((ret = xpc_pull_remote_vars_part(part)) != xpSuccess) {
+		if (ret != xpRetry) {
 			XPC_DEACTIVATE_PARTITION(part, ret);
 			return ret;
 		}
@@ -406,7 +406,7 @@
 
 	dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part));
 
-	if (xpc_setup_infrastructure(part) != xpcSuccess)
+	if (xpc_setup_infrastructure(part) != xpSuccess)
 		return;
 
 	/*
@@ -418,7 +418,7 @@
 
 	(void)xpc_part_ref(part);	/* this will always succeed */
 
-	if (xpc_make_first_contact(part) == xpcSuccess)
+	if (xpc_make_first_contact(part) == xpSuccess)
 		xpc_channel_mgr(part);
 
 	xpc_part_deref(part);
@@ -429,7 +429,7 @@
 static int
 xpc_activating(void *__partid)
 {
-	partid_t partid = (u64)__partid;
+	short partid = (u64)__partid;
 	struct xpc_partition *part = &xpc_partitions[partid];
 	unsigned long irq_flags;
 
@@ -470,7 +470,7 @@
 
 		spin_lock_irqsave(&part->act_lock, irq_flags);
 		part->act_state = XPC_P_INACTIVE;
-		XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__);
+		XPC_SET_REASON(part, xpPhysAddrRegFailed, __LINE__);
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 		part->remote_rp_pa = 0;
 		return 0;
@@ -488,7 +488,7 @@
 	xpc_disallow_hb(partid, xpc_vars);
 	xpc_mark_partition_inactive(part);
 
-	if (part->reason == xpcReactivating) {
+	if (part->reason == xpReactivating) {
 		/* interrupting ourselves results in activating partition */
 		xpc_IPI_send_reactivate(part);
 	}
@@ -499,7 +499,7 @@
 void
 xpc_activate_partition(struct xpc_partition *part)
 {
-	partid_t partid = XPC_PARTID(part);
+	short partid = XPC_PARTID(part);
 	unsigned long irq_flags;
 	struct task_struct *kthread;
 
@@ -508,7 +508,7 @@
 	DBUG_ON(part->act_state != XPC_P_INACTIVE);
 
 	part->act_state = XPC_P_ACTIVATION_REQ;
-	XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
+	XPC_SET_REASON(part, xpCloneKThread, __LINE__);
 
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
 
@@ -517,7 +517,7 @@
 	if (IS_ERR(kthread)) {
 		spin_lock_irqsave(&part->act_lock, irq_flags);
 		part->act_state = XPC_P_INACTIVE;
-		XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
+		XPC_SET_REASON(part, xpCloneKThreadFailed, __LINE__);
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 	}
 }
@@ -541,7 +541,7 @@
 irqreturn_t
 xpc_notify_IRQ_handler(int irq, void *dev_id)
 {
-	partid_t partid = (partid_t) (u64)dev_id;
+	short partid = (short)(u64)dev_id;
 	struct xpc_partition *part = &xpc_partitions[partid];
 
 	DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
@@ -643,7 +643,7 @@
 static int
 xpc_kthread_start(void *args)
 {
-	partid_t partid = XPC_UNPACK_ARG1(args);
+	short partid = XPC_UNPACK_ARG1(args);
 	u16 ch_number = XPC_UNPACK_ARG2(args);
 	struct xpc_partition *part = &xpc_partitions[partid];
 	struct xpc_channel *ch;
@@ -696,7 +696,7 @@
 		ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
 		spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-		xpc_disconnect_callout(ch, xpcDisconnecting);
+		xpc_disconnect_callout(ch, xpDisconnecting);
 
 		spin_lock_irqsave(&ch->lock, irq_flags);
 		ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
@@ -776,7 +776,7 @@
 			 * then we'll deadlock if all other kthreads assigned
 			 * to this channel are blocked in the channel's
 			 * registerer, because the only thing that will unblock
-			 * them is the xpcDisconnecting callout that this
+			 * them is the xpDisconnecting callout that this
 			 * failed kthread_run() would have made.
 			 */
 
@@ -796,7 +796,7 @@
 				 * to function.
 				 */
 				spin_lock_irqsave(&ch->lock, irq_flags);
-				XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources,
+				XPC_DISCONNECT_CHANNEL(ch, xpLackOfResources,
 						       &irq_flags);
 				spin_unlock_irqrestore(&ch->lock, irq_flags);
 			}
@@ -809,7 +809,7 @@
 xpc_disconnect_wait(int ch_number)
 {
 	unsigned long irq_flags;
-	partid_t partid;
+	short partid;
 	struct xpc_partition *part;
 	struct xpc_channel *ch;
 	int wakeup_channel_mgr;
@@ -857,9 +857,9 @@
 }
 
 static void
-xpc_do_exit(enum xpc_retval reason)
+xpc_do_exit(enum xp_retval reason)
 {
-	partid_t partid;
+	short partid;
 	int active_part_count, printed_waiting_msg = 0;
 	struct xpc_partition *part;
 	unsigned long printmsg_time, disengage_request_timeout = 0;
@@ -955,7 +955,7 @@
 	del_timer_sync(&xpc_hb_timer);
 	DBUG_ON(xpc_vars->heartbeating_to_mask != 0);
 
-	if (reason == xpcUnloading) {
+	if (reason == xpUnloading) {
 		/* take ourselves off of the reboot_notifier_list */
 		(void)unregister_reboot_notifier(&xpc_reboot_notifier);
 
@@ -981,20 +981,20 @@
 static int
 xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
 {
-	enum xpc_retval reason;
+	enum xp_retval reason;
 
 	switch (event) {
 	case SYS_RESTART:
-		reason = xpcSystemReboot;
+		reason = xpSystemReboot;
 		break;
 	case SYS_HALT:
-		reason = xpcSystemHalt;
+		reason = xpSystemHalt;
 		break;
 	case SYS_POWER_OFF:
-		reason = xpcSystemPoweroff;
+		reason = xpSystemPoweroff;
 		break;
 	default:
-		reason = xpcSystemGoingDown;
+		reason = xpSystemGoingDown;
 	}
 
 	xpc_do_exit(reason);
@@ -1008,7 +1008,7 @@
 xpc_die_disengage(void)
 {
 	struct xpc_partition *part;
-	partid_t partid;
+	short partid;
 	unsigned long engaged;
 	long time, printmsg_time, disengage_request_timeout;
 
@@ -1124,7 +1124,7 @@
 xpc_init(void)
 {
 	int ret;
-	partid_t partid;
+	short partid;
 	struct xpc_partition *part;
 	struct task_struct *kthread;
 	size_t buf_size;
@@ -1279,7 +1279,7 @@
 		/* mark this new thread as a non-starter */
 		complete(&xpc_discovery_exited);
 
-		xpc_do_exit(xpcUnloading);
+		xpc_do_exit(xpUnloading);
 		return -EBUSY;
 	}
 
@@ -1297,7 +1297,7 @@
 void __exit
 xpc_exit(void)
 {
-	xpc_do_exit(xpcUnloading);
+	xpc_do_exit(xpUnloading);
 }
 
 module_exit(xpc_exit);
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index acd3fd4..7dd4b58 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -403,7 +403,7 @@
 {
 	struct xpc_vars *remote_vars;
 	struct xpc_partition *part;
-	partid_t partid;
+	short partid;
 	bte_result_t bres;
 
 	remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
@@ -444,7 +444,7 @@
 		     (remote_vars->heartbeat_offline == 0)) ||
 		    !xpc_hb_allowed(sn_partition_id, remote_vars)) {
 
-			XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
+			XPC_DEACTIVATE_PARTITION(part, xpNoHeartbeat);
 			continue;
 		}
 
@@ -459,7 +459,7 @@
  * is large enough to contain a copy of their reserved page header and
  * part_nasids mask.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
 		  struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
 {
@@ -469,7 +469,7 @@
 
 	*remote_rp_pa = xpc_get_rsvd_page_pa(nasid);
 	if (*remote_rp_pa == 0)
-		return xpcNoRsvdPageAddr;
+		return xpNoRsvdPageAddr;
 
 	/* pull over the reserved page header and part_nasids mask */
 	bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp,
@@ -489,18 +489,18 @@
 
 	if (remote_rp->partid < 1 ||
 	    remote_rp->partid > (XP_MAX_PARTITIONS - 1)) {
-		return xpcInvalidPartid;
+		return xpInvalidPartid;
 	}
 
 	if (remote_rp->partid == sn_partition_id)
-		return xpcLocalPartid;
+		return xpLocalPartid;
 
 	if (XPC_VERSION_MAJOR(remote_rp->version) !=
 	    XPC_VERSION_MAJOR(XPC_RP_VERSION)) {
-		return xpcBadVersion;
+		return xpBadVersion;
 	}
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 
 /*
@@ -509,13 +509,13 @@
  * remote_vars points to a buffer that is cacheline aligned for BTE copies and
  * assumed to be of size XPC_RP_VARS_SIZE.
  */
-static enum xpc_retval
+static enum xp_retval
 xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
 {
 	int bres;
 
 	if (remote_vars_pa == 0)
-		return xpcVarsNotSet;
+		return xpVarsNotSet;
 
 	/* pull over the cross partition variables */
 	bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE,
@@ -525,10 +525,10 @@
 
 	if (XPC_VERSION_MAJOR(remote_vars->version) !=
 	    XPC_VERSION_MAJOR(XPC_V_VERSION)) {
-		return xpcBadVersion;
+		return xpBadVersion;
 	}
 
-	return xpcSuccess;
+	return xpSuccess;
 }
 
 /*
@@ -604,16 +604,16 @@
 	int reactivate = 0;
 	int stamp_diff;
 	struct timespec remote_rp_stamp = { 0, 0 };
-	partid_t partid;
+	short partid;
 	struct xpc_partition *part;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	/* pull over the reserved page structure */
 
 	remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer;
 
 	ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
-	if (ret != xpcSuccess) {
+	if (ret != xpSuccess) {
 		dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
 			 "which sent interrupt, reason=%d\n", nasid, ret);
 		return;
@@ -632,7 +632,7 @@
 	remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
 
 	ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
-	if (ret != xpcSuccess) {
+	if (ret != xpSuccess) {
 
 		dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
 			 "which sent interrupt, reason=%d\n", nasid, ret);
@@ -699,7 +699,7 @@
 					  &remote_rp_stamp, remote_rp_pa,
 					  remote_vars_pa, remote_vars);
 		part->reactivate_nasid = nasid;
-		XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
+		XPC_DEACTIVATE_PARTITION(part, xpReactivating);
 		return;
 	}
 
@@ -754,11 +754,11 @@
 
 	if (reactivate) {
 		part->reactivate_nasid = nasid;
-		XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
+		XPC_DEACTIVATE_PARTITION(part, xpReactivating);
 
 	} else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) &&
 		   xpc_partition_disengage_requested(1UL << partid)) {
-		XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown);
+		XPC_DEACTIVATE_PARTITION(part, xpOtherGoingDown);
 	}
 }
 
@@ -825,7 +825,7 @@
 int
 xpc_partition_disengaged(struct xpc_partition *part)
 {
-	partid_t partid = XPC_PARTID(part);
+	short partid = XPC_PARTID(part);
 	int disengaged;
 
 	disengaged = (xpc_partition_engaged(1UL << partid) == 0);
@@ -870,20 +870,20 @@
 /*
  * Mark specified partition as active.
  */
-enum xpc_retval
+enum xp_retval
 xpc_mark_partition_active(struct xpc_partition *part)
 {
 	unsigned long irq_flags;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
 
 	spin_lock_irqsave(&part->act_lock, irq_flags);
 	if (part->act_state == XPC_P_ACTIVATING) {
 		part->act_state = XPC_P_ACTIVE;
-		ret = xpcSuccess;
+		ret = xpSuccess;
 	} else {
-		DBUG_ON(part->reason == xpcSuccess);
+		DBUG_ON(part->reason == xpSuccess);
 		ret = part->reason;
 	}
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -896,7 +896,7 @@
  */
 void
 xpc_deactivate_partition(const int line, struct xpc_partition *part,
-			 enum xpc_retval reason)
+			 enum xp_retval reason)
 {
 	unsigned long irq_flags;
 
@@ -905,15 +905,15 @@
 	if (part->act_state == XPC_P_INACTIVE) {
 		XPC_SET_REASON(part, reason, line);
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
-		if (reason == xpcReactivating) {
+		if (reason == xpReactivating) {
 			/* we interrupt ourselves to reactivate partition */
 			xpc_IPI_send_reactivate(part);
 		}
 		return;
 	}
 	if (part->act_state == XPC_P_DEACTIVATING) {
-		if ((part->reason == xpcUnloading && reason != xpcUnloading) ||
-		    reason == xpcReactivating) {
+		if ((part->reason == xpUnloading && reason != xpUnloading) ||
+		    reason == xpReactivating) {
 			XPC_SET_REASON(part, reason, line);
 		}
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -982,10 +982,10 @@
 	int max_regions;
 	int nasid;
 	struct xpc_rsvd_page *rp;
-	partid_t partid;
+	short partid;
 	struct xpc_partition *part;
 	u64 *discovered_nasids;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
 						  xp_nasid_mask_bytes,
@@ -1063,12 +1063,12 @@
 
 			ret = xpc_get_remote_rp(nasid, discovered_nasids,
 						remote_rp, &remote_rp_pa);
-			if (ret != xpcSuccess) {
+			if (ret != xpSuccess) {
 				dev_dbg(xpc_part, "unable to get reserved page "
 					"from nasid %d, reason=%d\n", nasid,
 					ret);
 
-				if (ret == xpcLocalPartid)
+				if (ret == xpLocalPartid)
 					break;
 
 				continue;
@@ -1082,7 +1082,7 @@
 			/* pull over the cross partition variables */
 
 			ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
-			if (ret != xpcSuccess) {
+			if (ret != xpSuccess) {
 				dev_dbg(xpc_part, "unable to get XPC variables "
 					"from nasid %d, reason=%d\n", nasid,
 					ret);
@@ -1116,7 +1116,7 @@
 					"register xp_addr region 0x%016lx\n",
 					partid, remote_vars->amos_page_pa);
 
-				XPC_SET_REASON(part, xpcPhysAddrRegFailed,
+				XPC_SET_REASON(part, xpPhysAddrRegFailed,
 					       __LINE__);
 				break;
 			}
@@ -1151,8 +1151,8 @@
  * Given a partid, get the nasids owned by that partition from the
  * remote partition's reserved page.
  */
-enum xpc_retval
-xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
+enum xp_retval
+xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
 {
 	struct xpc_partition *part;
 	u64 part_nasid_pa;
@@ -1160,7 +1160,7 @@
 
 	part = &xpc_partitions[partid];
 	if (part->remote_rp_pa == 0)
-		return xpcPartitionDown;
+		return xpPartitionDown;
 
 	memset(nasid_mask, 0, XP_NASID_MASK_BYTES);
 
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index a9543c6..822dc8e 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -166,7 +166,7 @@
  * Packet was recevied by XPC and forwarded to us.
  */
 static void
-xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
+xpnet_receive(short partid, int channel, struct xpnet_message *msg)
 {
 	struct sk_buff *skb;
 	bte_result_t bret;
@@ -282,7 +282,7 @@
  * state or message reception on a connection.
  */
 static void
-xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel,
+xpnet_connection_activity(enum xp_retval reason, short partid, int channel,
 			  void *data, void *key)
 {
 	long bp;
@@ -291,13 +291,13 @@
 	DBUG_ON(channel != XPC_NET_CHANNEL);
 
 	switch (reason) {
-	case xpcMsgReceived:	/* message received */
+	case xpMsgReceived:	/* message received */
 		DBUG_ON(data == NULL);
 
 		xpnet_receive(partid, channel, (struct xpnet_message *)data);
 		break;
 
-	case xpcConnected:	/* connection completed to a partition */
+	case xpConnected:	/* connection completed to a partition */
 		spin_lock_bh(&xpnet_broadcast_lock);
 		xpnet_broadcast_partitions |= 1UL << (partid - 1);
 		bp = xpnet_broadcast_partitions;
@@ -330,7 +330,7 @@
 static int
 xpnet_dev_open(struct net_device *dev)
 {
-	enum xpc_retval ret;
+	enum xp_retval ret;
 
 	dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
 		"%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
@@ -340,7 +340,7 @@
 	ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
 			  XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
 			  XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS);
-	if (ret != xpcSuccess) {
+	if (ret != xpSuccess) {
 		dev_err(xpnet, "ifconfig up of %s failed on XPC connect, "
 			"ret=%d\n", dev->name, ret);
 
@@ -407,7 +407,7 @@
  * release the skb and then release our pending message structure.
  */
 static void
-xpnet_send_completed(enum xpc_retval reason, partid_t partid, int channel,
+xpnet_send_completed(enum xp_retval reason, short partid, int channel,
 		     void *__qm)
 {
 	struct xpnet_pending_msg *queued_msg = (struct xpnet_pending_msg *)__qm;
@@ -439,12 +439,12 @@
 xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct xpnet_pending_msg *queued_msg;
-	enum xpc_retval ret;
+	enum xp_retval ret;
 	struct xpnet_message *msg;
 	u64 start_addr, end_addr;
 	long dp;
 	u8 second_mac_octet;
-	partid_t dest_partid;
+	short dest_partid;
 	struct xpnet_dev_private *priv;
 	u16 embedded_bytes;
 
@@ -528,7 +528,7 @@
 
 		ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL,
 				   XPC_NOWAIT, (void **)&msg);
-		if (unlikely(ret != xpcSuccess))
+		if (unlikely(ret != xpSuccess))
 			continue;
 
 		msg->embedded_bytes = embedded_bytes;
@@ -557,7 +557,7 @@
 
 		ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg,
 				      xpnet_send_completed, queued_msg);
-		if (unlikely(ret != xpcSuccess)) {
+		if (unlikely(ret != xpSuccess)) {
 			atomic_dec(&queued_msg->use_count);
 			continue;
 		}
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 626ac08..da5feca 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -425,7 +425,7 @@
 			host->cclk = host->mclk;
 		} else {
 			clk = host->mclk / (2 * ios->clock) - 1;
-			if (clk > 256)
+			if (clk >= 256)
 				clk = 255;
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
@@ -512,6 +512,18 @@
 
 	host->plat = plat;
 	host->mclk = clk_get_rate(host->clk);
+	/*
+	 * According to the spec, mclk is max 100 MHz,
+	 * so we try to adjust the clock down to this,
+	 * (if possible).
+	 */
+	if (host->mclk > 100000000) {
+		ret = clk_set_rate(host->clk, 100000000);
+		if (ret < 0)
+			goto clk_disable;
+		host->mclk = clk_get_rate(host->clk);
+		DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
+	}
 	host->mmc = mmc;
 	host->base = ioremap(dev->res.start, SZ_4K);
 	if (!host->base) {
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7fb02e1..299118d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -187,7 +187,7 @@
 	struct mmc_request	*mrq;		/* Current request */
 	struct mmc_command	*cmd;		/* Current command */
 	struct mmc_data		*data;		/* Current data request */
-	int			data_early:1;	/* Data finished before cmd */
+	unsigned int		data_early:1;	/* Data finished before cmd */
 
 	struct scatterlist	*cur_sg;	/* We're working on this */
 	int			num_sg;		/* Entries left */
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 1bd69aa..17bc87a 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -374,7 +374,7 @@
 
 config MTD_SOLUTIONENGINE
 	tristate "CFI Flash device mapped on Hitachi SolutionEngine"
-	depends on SUPERH && MTD_CFI && MTD_REDBOOT_PARTS
+	depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS
 	help
 	  This enables access to the flash chips on the Hitachi SolutionEngine and
 	  similar boards. Say 'Y' if you are building a kernel for such a board.
@@ -480,13 +480,6 @@
 	  This enables access to the flash chips on the Hynix evaluation boards.
 	  If you have such a board, say 'Y'.
 
-config MTD_MPC1211
-	tristate "CFI Flash device mapped on Interface MPC-1211"
-	depends on SH_MPC1211 && MTD_CFI
-	help
-	  This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
-	  If you have such a board, say 'Y'.
-
 config MTD_OMAP_NOR
 	tristate "TI OMAP board mappings"
 	depends on MTD_CFI && ARCH_OMAP
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index a9cbe80..957fb5f 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -58,7 +58,6 @@
 obj-$(CONFIG_MTD_H720X)		+= h720x-flash.o
 obj-$(CONFIG_MTD_SBC8240)	+= sbc8240.o
 obj-$(CONFIG_MTD_NOR_TOTO)	+= omap-toto-flash.o
-obj-$(CONFIG_MTD_MPC1211)	+= mpc1211.o
 obj-$(CONFIG_MTD_IXP4XX)	+= ixp4xx.o
 obj-$(CONFIG_MTD_IXP2000)	+= ixp2000.o
 obj-$(CONFIG_MTD_WRSBC8260)	+= wr_sbc82xx_flash.o
diff --git a/drivers/mtd/maps/mpc1211.c b/drivers/mtd/maps/mpc1211.c
deleted file mode 100644
index 45a00fa..0000000
--- a/drivers/mtd/maps/mpc1211.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Flash on MPC-1211
- *
- * $Id: mpc1211.c,v 1.4 2004/09/16 23:27:13 gleixner Exp $
- *
- * (C) 2002 Interface, Saito.K & Jeanne
- *
- * GPL'd
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-static struct mtd_info *flash_mtd;
-static struct mtd_partition *parsed_parts;
-
-struct map_info mpc1211_flash_map = {
-	.name		= "MPC-1211 FLASH",
-	.size		= 0x80000,
-	.bankwidth	= 1,
-};
-
-static struct mtd_partition mpc1211_partitions[] = {
-	{
-		.name	= "IPL & ETH-BOOT",
-		.offset	= 0x00000000,
-		.size	= 0x10000,
-	},
-	{
-		.name	= "Flash FS",
-		.offset	= 0x00010000,
-		.size	= MTDPART_SIZ_FULL,
-	}
-};
-
-static int __init init_mpc1211_maps(void)
-{
-	int nr_parts;
-
-	mpc1211_flash_map.phys = 0;
-	mpc1211_flash_map.virt = (void __iomem *)P2SEGADDR(0);
-
-	simple_map_init(&mpc1211_flash_map);
-
-	printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
-	flash_mtd = do_map_probe("jedec_probe", &mpc1211_flash_map);
-	if (!flash_mtd) {
-		printk(KERN_NOTICE "Flash chips not detected at either possible location.\n");
-		return -ENXIO;
-	}
-	printk(KERN_NOTICE "MPC-1211: Flash at 0x%08lx\n", mpc1211_flash_map.virt & 0x1fffffff);
-	flash_mtd->module = THIS_MODULE;
-
-	parsed_parts = mpc1211_partitions;
-	nr_parts = ARRAY_SIZE(mpc1211_partitions);
-
-	add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
-	return 0;
-}
-
-static void __exit cleanup_mpc1211_maps(void)
-{
-	if (parsed_parts)
-		del_mtd_partitions(flash_mtd);
-	else
-		del_mtd_device(flash_mtd);
-	map_destroy(flash_mtd);
-}
-
-module_init(init_mpc1211_maps);
-module_exit(cleanup_mpc1211_maps);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Saito.K & Jeanne <ksaito@interface.co.jp>");
-MODULE_DESCRIPTION("MTD map driver for MPC-1211 boards. Interface");
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 6f8e7d4..2edda8c 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -319,7 +319,7 @@
 	{"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
 	 PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
 	{"3c980 Cyclone",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 
 	{"3c980C Python-T",
 	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
@@ -600,7 +600,6 @@
 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
 	unsigned int cur_rx, cur_tx;		/* The next free ring entry */
 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
-	struct net_device_stats stats;		/* Generic stats */
 	struct vortex_extra_stats xstats;	/* NIC-specific extra stats */
 	struct sk_buff *tx_skb;				/* Packet being eaten by bus master ctrl.  */
 	dma_addr_t tx_skb_dma;				/* Allocated DMA address for bus master ctrl DMA.   */
@@ -1875,7 +1874,7 @@
 
 	issue_and_wait(dev, TxReset);
 
-	vp->stats.tx_errors++;
+	dev->stats.tx_errors++;
 	if (vp->full_bus_master_tx) {
 		printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
 		if (vp->cur_tx - vp->dirty_tx > 0  &&  ioread32(ioaddr + DownListPtr) == 0)
@@ -1887,7 +1886,7 @@
 			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
 		iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	} else {
-		vp->stats.tx_dropped++;
+		dev->stats.tx_dropped++;
 		netif_wake_queue(dev);
 	}
 
@@ -1928,8 +1927,8 @@
 			}
 			dump_tx_ring(dev);
 		}
-		if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
-		if (tx_status & 0x38)  vp->stats.tx_aborted_errors++;
+		if (tx_status & 0x14)  dev->stats.tx_fifo_errors++;
+		if (tx_status & 0x38)  dev->stats.tx_aborted_errors++;
 		if (tx_status & 0x08)  vp->xstats.tx_max_collisions++;
 		iowrite8(0, ioaddr + TxStatus);
 		if (tx_status & 0x30) {			/* txJabber or txUnderrun */
@@ -2051,8 +2050,8 @@
 				if (vortex_debug > 2)
 				  printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
 						 dev->name, tx_status);
-				if (tx_status & 0x04) vp->stats.tx_fifo_errors++;
-				if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
+				if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
+				if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
 				if (tx_status & 0x30) {
 					issue_and_wait(dev, TxReset);
 				}
@@ -2350,7 +2349,7 @@
 				} else {
 					printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
 				}
-				/* vp->stats.tx_packets++;  Counted below. */
+				/* dev->stats.tx_packets++;  Counted below. */
 				dirty_tx++;
 			}
 			vp->dirty_tx = dirty_tx;
@@ -2409,12 +2408,12 @@
 			unsigned char rx_error = ioread8(ioaddr + RxErrors);
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
-			vp->stats.rx_errors++;
-			if (rx_error & 0x01)  vp->stats.rx_over_errors++;
-			if (rx_error & 0x02)  vp->stats.rx_length_errors++;
-			if (rx_error & 0x04)  vp->stats.rx_frame_errors++;
-			if (rx_error & 0x08)  vp->stats.rx_crc_errors++;
-			if (rx_error & 0x10)  vp->stats.rx_length_errors++;
+			dev->stats.rx_errors++;
+			if (rx_error & 0x01)  dev->stats.rx_over_errors++;
+			if (rx_error & 0x02)  dev->stats.rx_length_errors++;
+			if (rx_error & 0x04)  dev->stats.rx_frame_errors++;
+			if (rx_error & 0x08)  dev->stats.rx_crc_errors++;
+			if (rx_error & 0x10)  dev->stats.rx_length_errors++;
 		} else {
 			/* The packet length: up to 4.5K!. */
 			int pkt_len = rx_status & 0x1fff;
@@ -2446,7 +2445,7 @@
 				skb->protocol = eth_type_trans(skb, dev);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
-				vp->stats.rx_packets++;
+				dev->stats.rx_packets++;
 				/* Wait a limited time to go to next packet. */
 				for (i = 200; i >= 0; i--)
 					if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
@@ -2455,7 +2454,7 @@
 			} else if (vortex_debug > 0)
 				printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
 					   "size %d.\n", dev->name, pkt_len);
-			vp->stats.rx_dropped++;
+			dev->stats.rx_dropped++;
 		}
 		issue_and_wait(dev, RxDiscard);
 	}
@@ -2482,12 +2481,12 @@
 			unsigned char rx_error = rx_status >> 16;
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
-			vp->stats.rx_errors++;
-			if (rx_error & 0x01)  vp->stats.rx_over_errors++;
-			if (rx_error & 0x02)  vp->stats.rx_length_errors++;
-			if (rx_error & 0x04)  vp->stats.rx_frame_errors++;
-			if (rx_error & 0x08)  vp->stats.rx_crc_errors++;
-			if (rx_error & 0x10)  vp->stats.rx_length_errors++;
+			dev->stats.rx_errors++;
+			if (rx_error & 0x01)  dev->stats.rx_over_errors++;
+			if (rx_error & 0x02)  dev->stats.rx_length_errors++;
+			if (rx_error & 0x04)  dev->stats.rx_frame_errors++;
+			if (rx_error & 0x08)  dev->stats.rx_crc_errors++;
+			if (rx_error & 0x10)  dev->stats.rx_length_errors++;
 		} else {
 			/* The packet length: up to 4.5K!. */
 			int pkt_len = rx_status & 0x1fff;
@@ -2529,7 +2528,7 @@
 			}
 			netif_rx(skb);
 			dev->last_rx = jiffies;
-			vp->stats.rx_packets++;
+			dev->stats.rx_packets++;
 		}
 		entry = (++vp->cur_rx) % RX_RING_SIZE;
 	}
@@ -2591,7 +2590,7 @@
 	del_timer_sync(&vp->rx_oom_timer);
 	del_timer_sync(&vp->timer);
 
-	/* Turn off statistics ASAP.  We update vp->stats below. */
+	/* Turn off statistics ASAP.  We update dev->stats below. */
 	iowrite16(StatsDisable, ioaddr + EL3_CMD);
 
 	/* Disable the receiver and transmitter. */
@@ -2728,7 +2727,7 @@
 		update_stats(ioaddr, dev);
 		spin_unlock_irqrestore (&vp->lock, flags);
 	}
-	return &vp->stats;
+	return &dev->stats;
 }
 
 /*  Update statistics.
@@ -2748,18 +2747,18 @@
 	/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
 	/* Switch to the stats window, and read everything. */
 	EL3WINDOW(6);
-	vp->stats.tx_carrier_errors		+= ioread8(ioaddr + 0);
-	vp->stats.tx_heartbeat_errors		+= ioread8(ioaddr + 1);
-	vp->stats.tx_window_errors		+= ioread8(ioaddr + 4);
-	vp->stats.rx_fifo_errors		+= ioread8(ioaddr + 5);
-	vp->stats.tx_packets			+= ioread8(ioaddr + 6);
-	vp->stats.tx_packets			+= (ioread8(ioaddr + 9)&0x30) << 4;
+	dev->stats.tx_carrier_errors		+= ioread8(ioaddr + 0);
+	dev->stats.tx_heartbeat_errors		+= ioread8(ioaddr + 1);
+	dev->stats.tx_window_errors		+= ioread8(ioaddr + 4);
+	dev->stats.rx_fifo_errors		+= ioread8(ioaddr + 5);
+	dev->stats.tx_packets			+= ioread8(ioaddr + 6);
+	dev->stats.tx_packets			+= (ioread8(ioaddr + 9)&0x30) << 4;
 	/* Rx packets	*/			ioread8(ioaddr + 7);   /* Must read to clear */
 	/* Don't bother with register 9, an extension of registers 6&7.
 	   If we do use the 6&7 values the atomic update assumption above
 	   is invalid. */
-	vp->stats.rx_bytes 			+= ioread16(ioaddr + 10);
-	vp->stats.tx_bytes 			+= ioread16(ioaddr + 12);
+	dev->stats.rx_bytes 			+= ioread16(ioaddr + 10);
+	dev->stats.tx_bytes 			+= ioread16(ioaddr + 12);
 	/* Extra stats for get_ethtool_stats() */
 	vp->xstats.tx_multiple_collisions	+= ioread8(ioaddr + 2);
 	vp->xstats.tx_single_collisions         += ioread8(ioaddr + 3);
@@ -2767,14 +2766,14 @@
 	EL3WINDOW(4);
 	vp->xstats.rx_bad_ssd			+= ioread8(ioaddr + 12);
 
-	vp->stats.collisions = vp->xstats.tx_multiple_collisions
+	dev->stats.collisions = vp->xstats.tx_multiple_collisions
 		+ vp->xstats.tx_single_collisions
 		+ vp->xstats.tx_max_collisions;
 
 	{
 		u8 up = ioread8(ioaddr + 13);
-		vp->stats.rx_bytes += (up & 0x0f) << 16;
-		vp->stats.tx_bytes += (up & 0xf0) << 12;
+		dev->stats.rx_bytes += (up & 0x0f) << 16;
+		dev->stats.tx_bytes += (up & 0xf0) << 12;
 	}
 
 	EL3WINDOW(old_window >> 13);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index af46341..9f6cc8a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1273,20 +1273,6 @@
 	  To compile this driver as a module, choose M here. The module
 	  will be called pcnet32.
 
-config PCNET32_NAPI
-	bool "Use RX polling (NAPI)"
-	depends on PCNET32
-	help
-	  NAPI is a new driver API designed to reduce CPU and interrupt load
-	  when the driver is receiving lots of packets from the card. It is
-	  still somewhat experimental and thus not yet enabled by default.
-
-	  If your estimated Rx load is 10kpps or more, or if the card will be
-	  deployed on potentially unfriendly networks (e.g. in a firewall),
-	  then say Y here.
-
-	  If in doubt, say N.
-
 config AMD8111_ETH
 	tristate "AMD 8111 (new PCI lance) support"
 	depends on NET_PCI && PCI
@@ -2440,7 +2426,7 @@
 
 config EHEA
 	tristate "eHEA Ethernet support"
-	depends on IBMEBUS && INET && SPARSEMEM
+	depends on IBMEBUS && INET && SPARSEMEM && MEMORY_HOTPLUG
 	select INET_LRO
 	---help---
 	  This driver supports the IBM pSeries eHEA ethernet adapter.
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 82e9a5b..a0b4c85 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -499,19 +499,13 @@
         {
                 outb(0, ioaddr+DAYNA_RESET);	/* Assert the reset port */
                 inb(ioaddr+DAYNA_RESET);	/* Clear the reset */
-                if(sleep)
-                {
-                        long snap=jiffies;
-
-			/* Let card finish initializing, about 1/3 second */
-			while (time_before(jiffies, snap + HZ/3))
-                                schedule();
-                }
-                else
-                        mdelay(333);
+		if (sleep)
+			msleep(333);
+		else
+			mdelay(333);
         }
+
 	netif_wake_queue(dev);
-	return;
 }
 
 static void cops_load (struct net_device *dev)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 0afe522..9c2394d 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1,7 +1,7 @@
 /*
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
  * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
  *
  * Derived from Intel e1000 driver
  * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
@@ -36,7 +36,6 @@
  * A very incomplete list of things that need to be dealt with:
  *
  * TODO:
- * Wake on LAN.
  * Add more ethtool functions.
  * Fix abstruse irq enable/disable condition described here:
  *	http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2
@@ -638,21 +637,18 @@
 }
 
 /*
- *TODO: do something or get rid of this
+ * Force the PHY into power saving mode using vendor magic.
  */
 #ifdef CONFIG_PM
-static s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
+static void atl1_phy_enter_power_saving(struct atl1_hw *hw)
 {
-/*    s32 ret_val;
- *    u16 phy_data;
- */
+	atl1_write_phy_reg(hw, MII_DBG_ADDR, 0);
+	atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E);
+	atl1_write_phy_reg(hw, MII_DBG_ADDR, 2);
+	atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000);
+	atl1_write_phy_reg(hw, MII_DBG_ADDR, 3);
+	atl1_write_phy_reg(hw, MII_DBG_DATA, 0);
 
-/*
-    ret_val = atl1_write_phy_reg(hw, ...);
-    ret_val = atl1_write_phy_reg(hw, ...);
-    ....
-*/
-	return 0;
 }
 #endif
 
@@ -2784,64 +2780,93 @@
 	struct atl1_hw *hw = &adapter->hw;
 	u32 ctrl = 0;
 	u32 wufc = adapter->wol;
+	u32 val;
+	int retval;
+	u16 speed;
+	u16 duplex;
 
 	netif_device_detach(netdev);
 	if (netif_running(netdev))
 		atl1_down(adapter);
 
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+
 	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
 	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
-	if (ctrl & BMSR_LSTATUS)
+	val = ctrl & BMSR_LSTATUS;
+	if (val)
 		wufc &= ~ATLX_WUFC_LNKC;
 
-	/* reduce speed to 10/100M */
-	if (wufc) {
-		atl1_phy_enter_power_saving(hw);
-		/* if resume, let driver to re- setup link */
-		hw->phy_configured = false;
-		atl1_set_mac_addr(hw);
-		atlx_set_multi(netdev);
+	if (val && wufc) {
+		val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
+		if (val) {
+			if (netif_msg_ifdown(adapter))
+				dev_printk(KERN_DEBUG, &pdev->dev,
+					"error getting speed/duplex\n");
+			goto disable_wol;
+		}
 
 		ctrl = 0;
-		/* turn on magic packet wol */
+
+		/* enable magic packet WOL */
 		if (wufc & ATLX_WUFC_MAG)
-			ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
-
-		/* turn on Link change WOL */
-		if (wufc & ATLX_WUFC_LNKC)
-			ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
+			ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
 		iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
+		ioread32(hw->hw_addr + REG_WOL_CTRL);
 
-		/* turn on all-multi mode if wake on multicast is enabled */
-		ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL);
-		ctrl &= ~MAC_CTRL_DBG;
-		ctrl &= ~MAC_CTRL_PROMIS_EN;
-		if (wufc & ATLX_WUFC_MC)
-			ctrl |= MAC_CTRL_MC_ALL_EN;
-		else
-			ctrl &= ~MAC_CTRL_MC_ALL_EN;
-
-		/* turn on broadcast mode if wake on-BC is enabled */
-		if (wufc & ATLX_WUFC_BC)
+		/* configure the mac */
+		ctrl = MAC_CTRL_RX_EN;
+		ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 :
+			MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT);
+		if (duplex == FULL_DUPLEX)
+			ctrl |= MAC_CTRL_DUPLX;
+		ctrl |= (((u32)adapter->hw.preamble_len &
+			MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
+		if (adapter->vlgrp)
+			ctrl |= MAC_CTRL_RMV_VLAN;
+		if (wufc & ATLX_WUFC_MAG)
 			ctrl |= MAC_CTRL_BC_EN;
-		else
-			ctrl &= ~MAC_CTRL_BC_EN;
-
-		/* enable RX */
-		ctrl |= MAC_CTRL_RX_EN;
 		iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
-	} else {
-		iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
-		pci_enable_wake(pdev, PCI_D3hot, 0);
-		pci_enable_wake(pdev, PCI_D3cold, 0);
+		ioread32(hw->hw_addr + REG_MAC_CTRL);
+
+		/* poke the PHY */
+		ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+		ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+		iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
+		ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+
+		pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+		goto exit;
 	}
 
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
+	if (!val && wufc) {
+		ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
+		iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
+		ioread32(hw->hw_addr + REG_WOL_CTRL);
+		iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
+		ioread32(hw->hw_addr + REG_MAC_CTRL);
+		hw->phy_configured = false;
+		pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+		goto exit;
+	}
 
-	pci_set_power_state(pdev, PCI_D3hot);
+disable_wol:
+	iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
+	ioread32(hw->hw_addr + REG_WOL_CTRL);
+	ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+	ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+	iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
+	ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+	atl1_phy_enter_power_saving(hw);
+	hw->phy_configured = false;
+	pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+exit:
+	if (netif_running(netdev))
+		pci_disable_msi(adapter->pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
 }
@@ -2855,20 +2880,26 @@
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
-	/* FIXME: check and handle */
 	err = pci_enable_device(pdev);
+	if (err) {
+		if (netif_msg_ifup(adapter))
+			dev_printk(KERN_DEBUG, &pdev->dev,
+				"error enabling pci device\n");
+		return err;
+	}
+
+	pci_set_master(pdev);
+	iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
 
-	iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
-	atl1_reset(adapter);
+	atl1_reset_hw(&adapter->hw);
+	adapter->cmb.cmb->int_stats = 0;
 
 	if (netif_running(netdev))
 		atl1_up(adapter);
 	netif_device_attach(netdev);
 
-	atl1_via_workaround(adapter);
-
 	return 0;
 }
 #else
@@ -2876,6 +2907,13 @@
 #define atl1_resume NULL
 #endif
 
+static void atl1_shutdown(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PM
+	atl1_suspend(pdev, PMSG_SUSPEND);
+#endif
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void atl1_poll_controller(struct net_device *netdev)
 {
@@ -3122,7 +3160,8 @@
 	.probe = atl1_probe,
 	.remove = __devexit_p(atl1_remove),
 	.suspend = atl1_suspend,
-	.resume = atl1_resume
+	.resume = atl1_resume,
+	.shutdown = atl1_shutdown
 };
 
 /*
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 51893d6..a5015b1 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -1,7 +1,7 @@
 /*
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
  * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
  *
  * Derived from Intel e1000 driver
  * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index f06b854..b3e7fcf 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -2,7 +2,7 @@
  *
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
  * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
  * Copyright(c) 2007 Atheros Corporation. All rights reserved.
  *
  * Derived from Intel e1000 driver
diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h
index 3be7c09..297a03d 100644
--- a/drivers/net/atlx/atlx.h
+++ b/drivers/net/atlx/atlx.h
@@ -2,7 +2,7 @@
  *
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
  * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
  * Copyright(c) 2007 Atheros Corporation. All rights reserved.
  *
  * Derived from Intel e1000 driver
@@ -29,7 +29,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#define ATLX_DRIVER_VERSION "2.1.1"
+#define ATLX_DRIVER_VERSION "2.1.3"
 MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
 	Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
 MODULE_LICENSE("GPL");
@@ -460,6 +460,9 @@
 #define MII_ATLX_PSSR_100MBS		0x4000	/* 01=100Mbs */
 #define MII_ATLX_PSSR_1000MBS		0x8000	/* 10=1000Mbs */
 
+#define MII_DBG_ADDR			0x1D
+#define MII_DBG_DATA			0x1E
+
 /* PCI Command Register Bit Definitions */
 #define PCI_REG_COMMAND			0x04	/* PCI Command Register */
 #define CMD_IO_SPACE			0x0001
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6425603..50a40e4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1425,13 +1425,13 @@
 	res = netdev_set_master(slave_dev, bond_dev);
 	if (res) {
 		dprintk("Error %d calling netdev_set_master\n", res);
-		goto err_close;
+		goto err_restore_mac;
 	}
 	/* open the slave since the application closed it */
 	res = dev_open(slave_dev);
 	if (res) {
 		dprintk("Openning slave %s failed\n", slave_dev->name);
-		goto err_restore_mac;
+		goto err_unset_master;
 	}
 
 	new_slave->dev = slave_dev;
@@ -1444,7 +1444,7 @@
 		 */
 		res = bond_alb_init_slave(bond, new_slave);
 		if (res) {
-			goto err_unset_master;
+			goto err_close;
 		}
 	}
 
@@ -1619,7 +1619,7 @@
 
 	res = bond_create_slave_symlinks(bond_dev, slave_dev);
 	if (res)
-		goto err_unset_master;
+		goto err_close;
 
 	printk(KERN_INFO DRV_NAME
 	       ": %s: enslaving %s as a%s interface with a%s link.\n",
@@ -1631,12 +1631,12 @@
 	return 0;
 
 /* Undo stages on error */
-err_unset_master:
-	netdev_set_master(slave_dev, NULL);
-
 err_close:
 	dev_close(slave_dev);
 
+err_unset_master:
+	netdev_set_master(slave_dev, NULL);
+
 err_restore_mac:
 	if (!bond->params.fail_over_mac) {
 		memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
@@ -4936,7 +4936,9 @@
 	if (res < 0) {
 		rtnl_lock();
 		down_write(&bonding_rwsem);
-		goto out_bond;
+		bond_deinit(bond_dev);
+		unregister_netdevice(bond_dev);
+		goto out_rtnl;
 	}
 
 	return 0;
@@ -4990,9 +4992,10 @@
 		destroy_workqueue(bond->wq);
 	}
 
+	bond_destroy_sysfs();
+
 	rtnl_lock();
 	bond_free_all();
-	bond_destroy_sysfs();
 	rtnl_unlock();
 out:
 	return res;
@@ -5004,9 +5007,10 @@
 	unregister_netdevice_notifier(&bond_netdev_notifier);
 	unregister_inetaddr_notifier(&bond_inetaddr_notifier);
 
+	bond_destroy_sysfs();
+
 	rtnl_lock();
 	bond_free_all();
-	bond_destroy_sysfs();
 	rtnl_unlock();
 }
 
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 979c2d0..08f3d39 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -146,29 +146,29 @@
 						": Unable remove bond %s due to open references.\n",
 						ifname);
 					res = -EPERM;
-					goto out;
+					goto out_unlock;
 				}
 				printk(KERN_INFO DRV_NAME
 					": %s is being deleted...\n",
 					bond->dev->name);
 				bond_destroy(bond);
-				up_write(&bonding_rwsem);
-				rtnl_unlock();
-				goto out;
+				goto out_unlock;
 			}
 
 		printk(KERN_ERR DRV_NAME
 			": unable to delete non-existent bond %s\n", ifname);
 		res = -ENODEV;
-		up_write(&bonding_rwsem);
-		rtnl_unlock();
-		goto out;
+		goto out_unlock;
 	}
 
 err_no_cmd:
 	printk(KERN_ERR DRV_NAME
 		": no command found in bonding_masters. Use +ifname or -ifname.\n");
-	res = -EPERM;
+	return -EPERM;
+
+out_unlock:
+	up_write(&bonding_rwsem);
+	rtnl_unlock();
 
 	/* Always return either count or an error.  If you return 0, you'll
 	 * get called forever, which is bad.
@@ -1437,8 +1437,16 @@
 	 * configure multiple bonding devices.
 	 */
 	if (ret == -EEXIST) {
-		netdev_class = NULL;
-		return 0;
+		/* Is someone being kinky and naming a device bonding_master? */
+		if (__dev_get_by_name(&init_net,
+				      class_attr_bonding_masters.attr.name))
+			printk(KERN_ERR
+			       "network device named %s already exists in sysfs",
+			       class_attr_bonding_masters.attr.name);
+		else {
+			netdev_class = NULL;
+			return 0;
+		}
 	}
 
 	return ret;
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 4fdb13f..acebe43 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -71,6 +71,7 @@
 	USING_MSIX = (1 << 2),
 	QUEUES_BOUND = (1 << 3),
 	TP_PARITY_INIT = (1 << 4),
+	NAPI_INIT = (1 << 5),
 };
 
 struct fl_pg_chunk {
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 91ee727..579bee4 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -698,6 +698,7 @@
 void early_hw_init(struct adapter *adapter, const struct adapter_info *ai);
 int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
 		    int reset);
+int t3_replay_prep_adapter(struct adapter *adapter);
 void t3_led_ready(struct adapter *adapter);
 void t3_fatal_err(struct adapter *adapter);
 void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 05e5f59e..3a31272 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -421,6 +421,13 @@
 			netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll,
 				       64);
 	}
+
+	/*
+	 * netif_napi_add() can be called only once per napi_struct because it
+	 * adds each new napi_struct to a list.  Be careful not to call it a
+	 * second time, e.g., during EEH recovery, by making a note of it.
+	 */
+	adap->flags |= NAPI_INIT;
 }
 
 /*
@@ -896,7 +903,8 @@
 			goto out;
 
 		setup_rss(adap);
-		init_napi(adap);
+		if (!(adap->flags & NAPI_INIT))
+			init_napi(adap);
 		adap->flags |= FULL_INIT_DONE;
 	}
 
@@ -999,7 +1007,7 @@
 		return 0;
 
 	if (!adap_up && (err = cxgb_up(adapter)) < 0)
-		return err;
+		goto out;
 
 	t3_tp_set_offload_mode(adapter, 1);
 	tdev->lldev = adapter->port[0];
@@ -1061,10 +1069,8 @@
 	int other_ports = adapter->open_device_map & PORT_MASK;
 	int err;
 
-	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
-		quiesce_rx(adapter);
+	if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
 		return err;
-	}
 
 	set_bit(pi->port_id, &adapter->open_device_map);
 	if (is_offload(adapter) && !ofld_disable) {
@@ -1894,11 +1900,11 @@
 		u8 *fw_data;
 		struct ch_mem_range t;
 
-		if (!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
 		if (copy_from_user(&t, useraddr, sizeof(t)))
 			return -EFAULT;
-
+		/* Check t.len sanity ? */
 		fw_data = kmalloc(t.len, GFP_KERNEL);
 		if (!fw_data)
 			return -ENOMEM;
@@ -2424,14 +2430,11 @@
 	    test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
 		offload_close(&adapter->tdev);
 
-	/* Free sge resources */
-	t3_free_sge_resources(adapter);
-
 	adapter->flags &= ~FULL_INIT_DONE;
 
 	pci_disable_device(pdev);
 
-	/* Request a slot slot reset. */
+	/* Request a slot reset. */
 	return PCI_ERS_RESULT_NEED_RESET;
 }
 
@@ -2448,13 +2451,20 @@
 	if (pci_enable_device(pdev)) {
 		dev_err(&pdev->dev,
 			"Cannot re-enable PCI device after reset.\n");
-		return PCI_ERS_RESULT_DISCONNECT;
+		goto err;
 	}
 	pci_set_master(pdev);
+	pci_restore_state(pdev);
 
-	t3_prep_adapter(adapter, adapter->params.info, 1);
+	/* Free sge resources */
+	t3_free_sge_resources(adapter);
+
+	if (t3_replay_prep_adapter(adapter))
+		goto err;
 
 	return PCI_ERS_RESULT_RECOVERED;
+err:
+	return PCI_ERS_RESULT_DISCONNECT;
 }
 
 /**
@@ -2483,13 +2493,6 @@
 			netif_device_attach(netdev);
 		}
 	}
-
-	if (is_offload(adapter)) {
-		__set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
-		if (offload_open(adapter->port[0]))
-			printk(KERN_WARNING
-			       "Could not bring back offload capabilities\n");
-	}
 }
 
 static struct pci_error_handlers t3_err_handler = {
@@ -2608,6 +2611,7 @@
 	}
 
 	pci_set_master(pdev);
+	pci_save_state(pdev);
 
 	mmio_start = pci_resource_start(pdev, 0);
 	mmio_len = pci_resource_len(pdev, 0);
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index 02dbbb3..5671788 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -444,6 +444,14 @@
 
 #define A_PCIE_CFG 0x88
 
+#define S_ENABLELINKDWNDRST    21
+#define V_ENABLELINKDWNDRST(x) ((x) << S_ENABLELINKDWNDRST)
+#define F_ENABLELINKDWNDRST    V_ENABLELINKDWNDRST(1U)
+
+#define S_ENABLELINKDOWNRST    20
+#define V_ENABLELINKDOWNRST(x) ((x) << S_ENABLELINKDOWNRST)
+#define F_ENABLELINKDOWNRST    V_ENABLELINKDOWNRST(1U)
+
 #define S_PCIE_CLIDECEN    16
 #define V_PCIE_CLIDECEN(x) ((x) << S_PCIE_CLIDECEN)
 #define F_PCIE_CLIDECEN    V_PCIE_CLIDECEN(1U)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 98a6bbd..796eb30 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -539,6 +539,31 @@
 }
 
 /**
+ *	t3_reset_qset - reset a sge qset
+ *	@q: the queue set
+ *
+ *	Reset the qset structure.
+ *	the NAPI structure is preserved in the event of
+ *	the qset's reincarnation, for example during EEH recovery.
+ */
+static void t3_reset_qset(struct sge_qset *q)
+{
+	if (q->adap &&
+	    !(q->adap->flags & NAPI_INIT)) {
+		memset(q, 0, sizeof(*q));
+		return;
+	}
+
+	q->adap = NULL;
+	memset(&q->rspq, 0, sizeof(q->rspq));
+	memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
+	memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
+	q->txq_stopped = 0;
+	memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer));
+}
+
+
+/**
  *	free_qset - free the resources of an SGE queue set
  *	@adapter: the adapter owning the queue set
  *	@q: the queue set
@@ -594,7 +619,7 @@
 				  q->rspq.desc, q->rspq.phys_addr);
 	}
 
-	memset(q, 0, sizeof(*q));
+	t3_reset_qset(q);
 }
 
 /**
@@ -1365,7 +1390,7 @@
  */
 int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
 {
-	int ret; 
+	int ret;
 	local_bh_disable();
 	ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
 	local_bh_enable();
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index a99496a..d405a93 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -3264,6 +3264,7 @@
 
 	t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
 	t3_set_reg_field(adap, A_PCIE_CFG, 0,
+			 F_ENABLELINKDWNDRST | F_ENABLELINKDOWNRST |
 			 F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN);
 }
 
@@ -3655,3 +3656,30 @@
 	t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
 			 F_GPIO0_OUT_VAL);
 }
+
+int t3_replay_prep_adapter(struct adapter *adapter)
+{
+	const struct adapter_info *ai = adapter->params.info;
+	unsigned int i, j = 0;
+	int ret;
+
+	early_hw_init(adapter, ai);
+	ret = init_parity(adapter);
+	if (ret)
+		return ret;
+
+	for_each_port(adapter, i) {
+		struct port_info *p = adap2pinfo(adapter, i);
+		while (!adapter->params.vpd.port_type[j])
+			++j;
+
+		p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
+					ai->mdio_ops);
+
+		p->phy.ops->power_down(&p->phy, 1);
+		++j;
+	}
+
+return 0;
+}
+
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 12b4626..32a9a92 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -117,6 +117,9 @@
 
 	struct mutex	 addr_lock;	/* phy and eeprom access lock */
 
+	struct delayed_work phy_poll;
+	struct net_device  *ndev;
+
 	spinlock_t lock;
 
 	struct mii_if_info mii;
@@ -297,6 +300,10 @@
 	}
 }
 
+static void dm9000_schedule_poll(board_info_t *db)
+{
+	schedule_delayed_work(&db->phy_poll, HZ * 2);
+}
 
 /* Our watchdog timed out. Called by the networking layer */
 static void dm9000_timeout(struct net_device *dev)
@@ -465,6 +472,17 @@
  	.set_eeprom		= dm9000_set_eeprom,
 };
 
+static void
+dm9000_poll_work(struct work_struct *w)
+{
+	struct delayed_work *dw = container_of(w, struct delayed_work, work);
+	board_info_t *db = container_of(dw, board_info_t, phy_poll);
+
+	mii_check_media(&db->mii, netif_msg_link(db), 0);
+	
+	if (netif_running(db->ndev))
+		dm9000_schedule_poll(db);
+}
 
 /* dm9000_release_board
  *
@@ -503,7 +521,7 @@
 /*
  * Search DM9000 board, allocate space and register it
  */
-static int
+static int __devinit
 dm9000_probe(struct platform_device *pdev)
 {
 	struct dm9000_plat_data *pdata = pdev->dev.platform_data;
@@ -525,17 +543,21 @@
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 
-	dev_dbg(&pdev->dev, "dm9000_probe()");
+	dev_dbg(&pdev->dev, "dm9000_probe()\n");
 
 	/* setup board info structure */
 	db = (struct board_info *) ndev->priv;
 	memset(db, 0, sizeof (*db));
 
 	db->dev = &pdev->dev;
+	db->ndev = ndev;
 
 	spin_lock_init(&db->lock);
 	mutex_init(&db->addr_lock);
 
+	INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
+
+
 	if (pdev->num_resources < 2) {
 		ret = -ENODEV;
 		goto out;
@@ -761,6 +783,8 @@
 
 	mii_check_media(&db->mii, netif_msg_link(db), 1);
 	netif_start_queue(dev);
+	
+	dm9000_schedule_poll(db);
 
 	return 0;
 }
@@ -879,6 +903,8 @@
 	if (netif_msg_ifdown(db))
 		dev_dbg(db->dev, "shutting down %s\n", ndev->name);
 
+	cancel_delayed_work(&db->phy_poll);
+
 	netif_stop_queue(ndev);
 	netif_carrier_off(ndev);
 
@@ -1288,6 +1314,8 @@
 	spin_unlock_irqrestore(&db->lock,flags);
 
 	mutex_unlock(&db->addr_lock);
+
+	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
 	return ret;
 }
 
@@ -1301,6 +1329,7 @@
 	unsigned long flags;
 	unsigned long reg_save;
 
+	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
 	mutex_lock(&db->addr_lock);
 
 	spin_lock_irqsave(&db->lock,flags);
@@ -1372,7 +1401,7 @@
 	return 0;
 }
 
-static int
+static int __devexit
 dm9000_drv_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
@@ -1393,7 +1422,7 @@
 		.owner	 = THIS_MODULE,
 	},
 	.probe   = dm9000_probe,
-	.remove  = dm9000_drv_remove,
+	.remove  = __devexit_p(dm9000_drv_remove),
 	.suspend = dm9000_drv_suspend,
 	.resume  = dm9000_drv_resume,
 };
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 2a53875..f823b8b 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -648,6 +648,8 @@
 #define IFE_E_PHY_ID         0x02A80330
 #define IFE_PLUS_E_PHY_ID    0x02A80320
 #define IFE_C_E_PHY_ID       0x02A80310
+#define BME1000_E_PHY_ID     0x01410CB0
+#define BME1000_E_PHY_ID_R2  0x01410CB1
 
 /* M88E1000 Specific Registers */
 #define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
@@ -701,6 +703,14 @@
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
 
+/* BME1000 PHY Specific Control Register */
+#define BME1000_PSCR_ENABLE_DOWNSHIFT   0x0800 /* 1 = enable downshift */
+
+
+#define PHY_PAGE_SHIFT 5
+#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
+                           ((reg) & MAX_PHY_REG_ADDRESS))
+
 /*
  * Bits...
  * 15-5: page
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 38bfd0d..d3bc6f8 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -127,7 +127,7 @@
 		/* arrays of page information for packet split */
 		struct e1000_ps_page *ps_pages;
 	};
-
+	struct page *page;
 };
 
 struct e1000_ring {
@@ -304,6 +304,7 @@
 #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
 #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
 #define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
+#define FLAG_IS_ICH                       (1 << 9)
 #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
 #define FLAG_IS_QUAD_PORT_A               (1 << 12)
 #define FLAG_IS_QUAD_PORT                 (1 << 13)
@@ -386,6 +387,7 @@
 						 bool state);
 extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
 extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
+extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
 
 extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
 extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
@@ -443,6 +445,9 @@
 extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
 extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
+extern s32 e1000e_determine_phy_address(struct e1000_hw *hw);
+extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
 extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
 extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index ce045ac..a14561f 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -494,8 +494,12 @@
 		for (i = 0; i < last_word - first_word + 1; i++) {
 			ret_val = e1000_read_nvm(hw, first_word + i, 1,
 						      &eeprom_buff[i]);
-			if (ret_val)
+			if (ret_val) {
+				/* a read error occurred, throw away the
+				 * result */
+				memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
 				break;
+			}
 		}
 	}
 
@@ -803,8 +807,7 @@
 	/* restore previous status */
 	ew32(STATUS, before);
 
-	if ((mac->type != e1000_ich8lan) &&
-	    (mac->type != e1000_ich9lan)) {
+	if (!(adapter->flags & FLAG_IS_ICH)) {
 		REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
 		REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF);
 		REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF);
@@ -824,15 +827,13 @@
 
 	REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000);
 
-	before = (((mac->type == e1000_ich8lan) ||
-		   (mac->type == e1000_ich9lan)) ? 0x06C3B33E : 0x06DFB3FE);
+	before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE);
 	REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB);
 	REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000);
 
 	REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF);
 	REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
-	if ((mac->type != e1000_ich8lan) &&
-	    (mac->type != e1000_ich9lan))
+	if (!(adapter->flags & FLAG_IS_ICH))
 		REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
 	REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
 	REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
@@ -911,9 +912,7 @@
 
 	/* Test each interrupt */
 	for (i = 0; i < 10; i++) {
-
-		if (((adapter->hw.mac.type == e1000_ich8lan) ||
-		     (adapter->hw.mac.type == e1000_ich9lan)) && i == 8)
+		if ((adapter->flags & FLAG_IS_ICH) && (i == 8))
 			continue;
 
 		/* Interrupt to test */
@@ -1184,6 +1183,7 @@
 	struct e1000_hw *hw = &adapter->hw;
 	u32 ctrl_reg = 0;
 	u32 stat_reg = 0;
+	u16 phy_reg = 0;
 
 	hw->mac.autoneg = 0;
 
@@ -1211,6 +1211,28 @@
 			     E1000_CTRL_SPD_100 |/* Force Speed to 100 */
 			     E1000_CTRL_FD);	 /* Force Duplex to FULL */
 		break;
+	case e1000_phy_bm:
+		/* Set Default MAC Interface speed to 1GB */
+		e1e_rphy(hw, PHY_REG(2, 21), &phy_reg);
+		phy_reg &= ~0x0007;
+		phy_reg |= 0x006;
+		e1e_wphy(hw, PHY_REG(2, 21), phy_reg);
+		/* Assert SW reset for above settings to take effect */
+		e1000e_commit_phy(hw);
+		mdelay(1);
+		/* Force Full Duplex */
+		e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
+		e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C);
+		/* Set Link Up (in force link) */
+		e1e_rphy(hw, PHY_REG(776, 16), &phy_reg);
+		e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040);
+		/* Force Link */
+		e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
+		e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040);
+		/* Set Early Link Enable */
+		e1e_rphy(hw, PHY_REG(769, 20), &phy_reg);
+		e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400);
+		/* fall through */
 	default:
 		/* force 1000, set loopback */
 		e1e_wphy(hw, PHY_CONTROL, 0x4140);
@@ -1224,8 +1246,7 @@
 			     E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
 			     E1000_CTRL_FD);	 /* Force Duplex to FULL */
 
-		if ((adapter->hw.mac.type == e1000_ich8lan) ||
-		    (adapter->hw.mac.type == e1000_ich9lan))
+		if (adapter->flags & FLAG_IS_ICH)
 			ctrl_reg |= E1000_CTRL_SLU;	/* Set Link Up */
 	}
 
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index a930e6d..74f263a 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -216,6 +216,21 @@
 #define IGP01E1000_PHY_LINK_HEALTH	0x13 /* PHY Link Health */
 #define IGP02E1000_PHY_POWER_MGMT	0x19 /* Power Management */
 #define IGP01E1000_PHY_PAGE_SELECT	0x1F /* Page Select */
+#define BM_PHY_PAGE_SELECT		22   /* Page Select for BM */
+#define IGP_PAGE_SHIFT			5
+#define PHY_REG_MASK			0x1F
+
+#define BM_WUC_PAGE			800
+#define BM_WUC_ADDRESS_OPCODE		0x11
+#define BM_WUC_DATA_OPCODE		0x12
+#define BM_WUC_ENABLE_PAGE		769
+#define BM_WUC_ENABLE_REG		17
+#define BM_WUC_ENABLE_BIT		(1 << 2)
+#define BM_WUC_HOST_WU_BIT		(1 << 4)
+
+#define BM_WUC	PHY_REG(BM_WUC_PAGE, 1)
+#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
+#define BM_WUS	PHY_REG(BM_WUC_PAGE, 3)
 
 #define IGP01E1000_PHY_PCS_INIT_REG	0x00B4
 #define IGP01E1000_PHY_POLARITY_MASK	0x0078
@@ -331,10 +346,16 @@
 #define E1000_DEV_ID_ICH8_IFE_G			0x10C5
 #define E1000_DEV_ID_ICH8_IGP_M			0x104D
 #define E1000_DEV_ID_ICH9_IGP_AMT		0x10BD
+#define E1000_DEV_ID_ICH9_IGP_M_AMT		0x10F5
+#define E1000_DEV_ID_ICH9_IGP_M			0x10BF
+#define E1000_DEV_ID_ICH9_IGP_M_V		0x10CB
 #define E1000_DEV_ID_ICH9_IGP_C			0x294C
 #define E1000_DEV_ID_ICH9_IFE			0x10C0
 #define E1000_DEV_ID_ICH9_IFE_GT		0x10C3
 #define E1000_DEV_ID_ICH9_IFE_G			0x10C2
+#define E1000_DEV_ID_ICH10_R_BM_LM		0x10CC
+#define E1000_DEV_ID_ICH10_R_BM_LF		0x10CD
+#define E1000_DEV_ID_ICH10_R_BM_V		0x10CE
 
 #define E1000_FUNC_1 1
 
@@ -378,6 +399,7 @@
 	e1000_phy_gg82563,
 	e1000_phy_igp_3,
 	e1000_phy_ife,
+	e1000_phy_bm,
 };
 
 enum e1000_bus_width {
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 768485d..9e38452 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -38,6 +38,12 @@
  * 82566DM Gigabit Network Connection
  * 82566MC Gigabit Network Connection
  * 82566MM Gigabit Network Connection
+ * 82567LM Gigabit Network Connection
+ * 82567LF Gigabit Network Connection
+ * 82567LM-2 Gigabit Network Connection
+ * 82567LF-2 Gigabit Network Connection
+ * 82567V-2 Gigabit Network Connection
+ * 82562GT-3 10/100 Network Connection
  */
 
 #include <linux/netdevice.h>
@@ -198,6 +204,19 @@
 	phy->addr			= 1;
 	phy->reset_delay_us		= 100;
 
+	/*
+	 * We may need to do this twice - once for IGP and if that fails,
+	 * we'll set BM func pointers and try again
+	 */
+	ret_val = e1000e_determine_phy_address(hw);
+	if (ret_val) {
+		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
+		hw->phy.ops.read_phy_reg  = e1000e_read_phy_reg_bm;
+		ret_val = e1000e_determine_phy_address(hw);
+		if (ret_val)
+			return ret_val;
+	}
+
 	phy->id = 0;
 	while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
 	       (i++ < 100)) {
@@ -219,6 +238,13 @@
 		phy->type = e1000_phy_ife;
 		phy->autoneg_mask = E1000_ALL_NOT_GIG;
 		break;
+	case BME1000_E_PHY_ID:
+		phy->type = e1000_phy_bm;
+		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+		hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm;
+		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
+		hw->phy.ops.commit_phy = e1000e_phy_sw_reset;
+		break;
 	default:
 		return -E1000_ERR_PHY;
 		break;
@@ -664,6 +690,7 @@
 		return e1000_get_phy_info_ife_ich8lan(hw);
 		break;
 	case e1000_phy_igp_3:
+	case e1000_phy_bm:
 		return e1000e_get_phy_info_igp(hw);
 		break;
 	default:
@@ -728,7 +755,7 @@
 	s32 ret_val = 0;
 	u16 data;
 
-	if (phy->type != e1000_phy_igp_3)
+	if (phy->type == e1000_phy_ife)
 		return ret_val;
 
 	phy_ctrl = er32(PHY_CTRL);
@@ -1918,8 +1945,35 @@
 		ret_val = e1000e_copper_link_setup_igp(hw);
 		if (ret_val)
 			return ret_val;
+	} else if (hw->phy.type == e1000_phy_bm) {
+		ret_val = e1000e_copper_link_setup_m88(hw);
+		if (ret_val)
+			return ret_val;
 	}
 
+	if (hw->phy.type == e1000_phy_ife) {
+		ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &reg_data);
+		if (ret_val)
+			return ret_val;
+
+		reg_data &= ~IFE_PMC_AUTO_MDIX;
+
+		switch (hw->phy.mdix) {
+		case 1:
+			reg_data &= ~IFE_PMC_FORCE_MDIX;
+			break;
+		case 2:
+			reg_data |= IFE_PMC_FORCE_MDIX;
+			break;
+		case 0:
+		default:
+			reg_data |= IFE_PMC_AUTO_MDIX;
+			break;
+		}
+		ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data);
+		if (ret_val)
+			return ret_val;
+	}
 	return e1000e_setup_copper_link(hw);
 }
 
@@ -2127,6 +2181,31 @@
 }
 
 /**
+ *  e1000e_disable_gig_wol_ich8lan - disable gig during WoL
+ *  @hw: pointer to the HW structure
+ *
+ *  During S0 to Sx transition, it is possible the link remains at gig
+ *  instead of negotiating to a lower speed.  Before going to Sx, set
+ *  'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
+ *  to a lower speed.
+ *
+ *  Should only be called for ICH9 devices.
+ **/
+void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
+{
+	u32 phy_ctrl;
+
+	if (hw->mac.type == e1000_ich9lan) {
+		phy_ctrl = er32(PHY_CTRL);
+		phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
+		            E1000_PHY_CTRL_GBE_DISABLE;
+		ew32(PHY_CTRL, phy_ctrl);
+	}
+
+	return;
+}
+
+/**
  *  e1000_cleanup_led_ich8lan - Restore the default LED operation
  *  @hw: pointer to the HW structure
  *
@@ -2247,6 +2326,7 @@
 struct e1000_info e1000_ich8_info = {
 	.mac			= e1000_ich8lan,
 	.flags			= FLAG_HAS_WOL
+				  | FLAG_IS_ICH
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
 				  | FLAG_HAS_AMT
@@ -2262,6 +2342,7 @@
 struct e1000_info e1000_ich9_info = {
 	.mac			= e1000_ich9lan,
 	.flags			= FLAG_HAS_JUMBO_FRAMES
+				  | FLAG_IS_ICH
 				  | FLAG_HAS_WOL
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 8991ab8..8cbb40f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -43,10 +43,11 @@
 #include <linux/if_vlan.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
+#include <linux/pm_qos_params.h>
 
 #include "e1000.h"
 
-#define DRV_VERSION "0.2.1"
+#define DRV_VERSION "0.3.3.3-k2"
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -341,6 +342,89 @@
 }
 
 /**
+ * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
+ * @adapter: address of board private structure
+ * @rx_ring: pointer to receive ring structure
+ * @cleaned_count: number of buffers to allocate this pass
+ **/
+
+static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
+                                         int cleaned_count)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct e1000_rx_desc *rx_desc;
+	struct e1000_ring *rx_ring = adapter->rx_ring;
+	struct e1000_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	unsigned int bufsz = 256 -
+	                     16 /* for skb_reserve */ -
+	                     NET_IP_ALIGN;
+
+	i = rx_ring->next_to_use;
+	buffer_info = &rx_ring->buffer_info[i];
+
+	while (cleaned_count--) {
+		skb = buffer_info->skb;
+		if (skb) {
+			skb_trim(skb, 0);
+			goto check_page;
+		}
+
+		skb = netdev_alloc_skb(netdev, bufsz);
+		if (unlikely(!skb)) {
+			/* Better luck next round */
+			adapter->alloc_rx_buff_failed++;
+			break;
+		}
+
+		/* Make buffer alignment 2 beyond a 16 byte boundary
+		 * this will result in a 16 byte aligned IP header after
+		 * the 14 byte MAC header is removed
+		 */
+		skb_reserve(skb, NET_IP_ALIGN);
+
+		buffer_info->skb = skb;
+check_page:
+		/* allocate a new page if necessary */
+		if (!buffer_info->page) {
+			buffer_info->page = alloc_page(GFP_ATOMIC);
+			if (unlikely(!buffer_info->page)) {
+				adapter->alloc_rx_buff_failed++;
+				break;
+			}
+		}
+
+		if (!buffer_info->dma)
+			buffer_info->dma = pci_map_page(pdev,
+			                                buffer_info->page, 0,
+			                                PAGE_SIZE,
+			                                PCI_DMA_FROMDEVICE);
+
+		rx_desc = E1000_RX_DESC(*rx_ring, i);
+		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+
+		if (unlikely(++i == rx_ring->count))
+			i = 0;
+		buffer_info = &rx_ring->buffer_info[i];
+	}
+
+	if (likely(rx_ring->next_to_use != i)) {
+		rx_ring->next_to_use = i;
+		if (unlikely(i-- == 0))
+			i = (rx_ring->count - 1);
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64). */
+		wmb();
+		writel(i, adapter->hw.hw_addr + rx_ring->tail);
+	}
+}
+
+/**
  * e1000_clean_rx_irq - Send received data up the network stack; legacy
  * @adapter: board private structure
  *
@@ -783,6 +867,186 @@
 }
 
 /**
+ * e1000_consume_page - helper function
+ **/
+static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
+                               u16 length)
+{
+	bi->page = NULL;
+	skb->len += length;
+	skb->data_len += length;
+	skb->truesize += length;
+}
+
+/**
+ * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
+ * @adapter: board private structure
+ *
+ * the return value indicates whether actual cleaning was done, there
+ * is no guarantee that everything was cleaned
+ **/
+
+static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
+                                     int *work_done, int work_to_do)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct e1000_ring *rx_ring = adapter->rx_ring;
+	struct e1000_rx_desc *rx_desc, *next_rxd;
+	struct e1000_buffer *buffer_info, *next_buffer;
+	u32 length;
+	unsigned int i;
+	int cleaned_count = 0;
+	bool cleaned = false;
+	unsigned int total_rx_bytes=0, total_rx_packets=0;
+
+	i = rx_ring->next_to_clean;
+	rx_desc = E1000_RX_DESC(*rx_ring, i);
+	buffer_info = &rx_ring->buffer_info[i];
+
+	while (rx_desc->status & E1000_RXD_STAT_DD) {
+		struct sk_buff *skb;
+		u8 status;
+
+		if (*work_done >= work_to_do)
+			break;
+		(*work_done)++;
+
+		status = rx_desc->status;
+		skb = buffer_info->skb;
+		buffer_info->skb = NULL;
+
+		++i;
+		if (i == rx_ring->count)
+			i = 0;
+		next_rxd = E1000_RX_DESC(*rx_ring, i);
+		prefetch(next_rxd);
+
+		next_buffer = &rx_ring->buffer_info[i];
+
+		cleaned = true;
+		cleaned_count++;
+		pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE,
+		               PCI_DMA_FROMDEVICE);
+		buffer_info->dma = 0;
+
+		length = le16_to_cpu(rx_desc->length);
+
+		/* errors is only valid for DD + EOP descriptors */
+		if (unlikely((status & E1000_RXD_STAT_EOP) &&
+		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
+				/* recycle both page and skb */
+				buffer_info->skb = skb;
+				/* an error means any chain goes out the window
+				 * too */
+				if (rx_ring->rx_skb_top)
+					dev_kfree_skb(rx_ring->rx_skb_top);
+				rx_ring->rx_skb_top = NULL;
+				goto next_desc;
+		}
+
+#define rxtop rx_ring->rx_skb_top
+		if (!(status & E1000_RXD_STAT_EOP)) {
+			/* this descriptor is only the beginning (or middle) */
+			if (!rxtop) {
+				/* this is the beginning of a chain */
+				rxtop = skb;
+				skb_fill_page_desc(rxtop, 0, buffer_info->page,
+				                   0, length);
+			} else {
+				/* this is the middle of a chain */
+				skb_fill_page_desc(rxtop,
+				    skb_shinfo(rxtop)->nr_frags,
+				    buffer_info->page, 0, length);
+				/* re-use the skb, only consumed the page */
+				buffer_info->skb = skb;
+			}
+			e1000_consume_page(buffer_info, rxtop, length);
+			goto next_desc;
+		} else {
+			if (rxtop) {
+				/* end of the chain */
+				skb_fill_page_desc(rxtop,
+				    skb_shinfo(rxtop)->nr_frags,
+				    buffer_info->page, 0, length);
+				/* re-use the current skb, we only consumed the
+				 * page */
+				buffer_info->skb = skb;
+				skb = rxtop;
+				rxtop = NULL;
+				e1000_consume_page(buffer_info, skb, length);
+			} else {
+				/* no chain, got EOP, this buf is the packet
+				 * copybreak to save the put_page/alloc_page */
+				if (length <= copybreak &&
+				    skb_tailroom(skb) >= length) {
+					u8 *vaddr;
+					vaddr = kmap_atomic(buffer_info->page,
+					                   KM_SKB_DATA_SOFTIRQ);
+					memcpy(skb_tail_pointer(skb), vaddr,
+					       length);
+					kunmap_atomic(vaddr,
+					              KM_SKB_DATA_SOFTIRQ);
+					/* re-use the page, so don't erase
+					 * buffer_info->page */
+					skb_put(skb, length);
+				} else {
+					skb_fill_page_desc(skb, 0,
+					                   buffer_info->page, 0,
+				                           length);
+					e1000_consume_page(buffer_info, skb,
+					                   length);
+				}
+			}
+		}
+
+		/* Receive Checksum Offload XXX recompute due to CRC strip? */
+		e1000_rx_checksum(adapter,
+		                  (u32)(status) |
+		                  ((u32)(rx_desc->errors) << 24),
+		                  le16_to_cpu(rx_desc->csum), skb);
+
+		/* probably a little skewed due to removing CRC */
+		total_rx_bytes += skb->len;
+		total_rx_packets++;
+
+		/* eth type trans needs skb->data to point to something */
+		if (!pskb_may_pull(skb, ETH_HLEN)) {
+			ndev_err(netdev, "pskb_may_pull failed.\n");
+			dev_kfree_skb(skb);
+			goto next_desc;
+		}
+
+		e1000_receive_skb(adapter, netdev, skb, status,
+		                  rx_desc->special);
+
+next_desc:
+		rx_desc->status = 0;
+
+		/* return some buffers to hardware, one at a time is too slow */
+		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
+			adapter->alloc_rx_buf(adapter, cleaned_count);
+			cleaned_count = 0;
+		}
+
+		/* use prefetched values */
+		rx_desc = next_rxd;
+		buffer_info = next_buffer;
+	}
+	rx_ring->next_to_clean = i;
+
+	cleaned_count = e1000_desc_unused(rx_ring);
+	if (cleaned_count)
+		adapter->alloc_rx_buf(adapter, cleaned_count);
+
+	adapter->total_rx_bytes += total_rx_bytes;
+	adapter->total_rx_packets += total_rx_packets;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
+	return cleaned;
+}
+
+/**
  * e1000_clean_rx_ring - Free Rx Buffers per Queue
  * @adapter: board private structure
  **/
@@ -802,6 +1066,10 @@
 				pci_unmap_single(pdev, buffer_info->dma,
 						 adapter->rx_buffer_len,
 						 PCI_DMA_FROMDEVICE);
+			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
+				pci_unmap_page(pdev, buffer_info->dma,
+				               PAGE_SIZE,
+				               PCI_DMA_FROMDEVICE);
 			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
 				pci_unmap_single(pdev, buffer_info->dma,
 						 adapter->rx_ps_bsize0,
@@ -809,6 +1077,11 @@
 			buffer_info->dma = 0;
 		}
 
+		if (buffer_info->page) {
+			put_page(buffer_info->page);
+			buffer_info->page = NULL;
+		}
+
 		if (buffer_info->skb) {
 			dev_kfree_skb(buffer_info->skb);
 			buffer_info->skb = NULL;
@@ -1755,10 +2028,12 @@
 	 * a lot of memory, since we allocate 3 pages at all times
 	 * per packet.
 	 */
-	adapter->rx_ps_pages = 0;
 	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
+	if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) &&
+	    (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
 		adapter->rx_ps_pages = pages;
+	else
+		adapter->rx_ps_pages = 0;
 
 	if (adapter->rx_ps_pages) {
 		/* Configure extra packet-split registers */
@@ -1819,9 +2094,12 @@
 			sizeof(union e1000_rx_desc_packet_split);
 		adapter->clean_rx = e1000_clean_rx_irq_ps;
 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
+	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
+		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
+		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
+		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
 	} else {
-		rdlen = rx_ring->count *
-			sizeof(struct e1000_rx_desc);
+		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
 		adapter->clean_rx = e1000_clean_rx_irq;
 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
 	}
@@ -1885,8 +2163,21 @@
 	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
 	 */
 	if ((adapter->flags & FLAG_HAS_ERT) &&
-	    (adapter->netdev->mtu > ETH_DATA_LEN))
-		ew32(ERT, E1000_ERT_2048);
+	    (adapter->netdev->mtu > ETH_DATA_LEN)) {
+		u32 rxdctl = er32(RXDCTL(0));
+		ew32(RXDCTL(0), rxdctl | 0x3);
+		ew32(ERT, E1000_ERT_2048 | (1 << 13));
+		/*
+		 * With jumbo frames and early-receive enabled, excessive
+		 * C4->C2 latencies result in dropped transactions.
+		 */
+		pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
+					  e1000e_driver_name, 55);
+	} else {
+		pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
+					  e1000e_driver_name,
+					  PM_QOS_DEFAULT_VALUE);
+	}
 
 	/* Enable Receives */
 	ew32(RCTL, rctl);
@@ -2155,6 +2446,14 @@
 
 	/* Allow time for pending master requests to run */
 	mac->ops.reset_hw(hw);
+
+	/*
+	 * For parts with AMT enabled, let the firmware know
+	 * that the network interface is in control
+	 */
+	if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw))
+		e1000_get_hw_control(adapter);
+
 	ew32(WUC, 0);
 
 	if (mac->ops.init_hw(hw))
@@ -3469,6 +3768,8 @@
 	 * means we reserve 2 more, this pushes us to allocate from the next
 	 * larger slab size.
 	 * i.e. RXBUFFER_2048 --> size-4096 slab
+	 * However with the new *_jumbo_rx* routines, jumbo receives will use
+	 * fragmented skbs
 	 */
 
 	if (max_frame <= 256)
@@ -3626,6 +3927,9 @@
 			ew32(CTRL_EXT, ctrl_ext);
 		}
 
+		if (adapter->flags & FLAG_IS_ICH)
+			e1000e_disable_gig_wol_ich8lan(&adapter->hw);
+
 		/* Allow time for pending master requests to run */
 		e1000e_disable_pcie_master(&adapter->hw);
 
@@ -4292,6 +4596,13 @@
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
+
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
 
 	{ }	/* terminate list */
 };
@@ -4326,7 +4637,9 @@
 	printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n",
 	       e1000e_driver_name);
 	ret = pci_register_driver(&e1000_driver);
-
+	pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name,
+			       PM_QOS_DEFAULT_VALUE);
+				
 	return ret;
 }
 module_init(e1000_init_module);
@@ -4340,6 +4653,7 @@
 static void __exit e1000_exit_module(void)
 {
 	pci_unregister_driver(&e1000_driver);
+	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name);
 }
 module_exit(e1000_exit_module);
 
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index e102332..b133dcf 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -34,6 +34,9 @@
 static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
 static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
 static s32 e1000_wait_autoneg(struct e1000_hw *hw);
+static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
+static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
+					  u16 *data, bool read);
 
 /* Cable length tables */
 static const u16 e1000_m88_cable_length_table[] =
@@ -465,6 +468,10 @@
 	if (phy->disable_polarity_correction == 1)
 		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
 
+	/* Enable downshift on BM (disabled by default) */
+	if (phy->type == e1000_phy_bm)
+		phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
+
 	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
 	if (ret_val)
 		return ret_val;
@@ -1776,6 +1783,10 @@
 	case IFE_C_E_PHY_ID:
 		phy_type = e1000_phy_ife;
 		break;
+	case BME1000_E_PHY_ID:
+	case BME1000_E_PHY_ID_R2:
+		phy_type = e1000_phy_bm;
+		break;
 	default:
 		phy_type = e1000_phy_unknown;
 		break;
@@ -1784,6 +1795,273 @@
 }
 
 /**
+ *  e1000e_determine_phy_address - Determines PHY address.
+ *  @hw: pointer to the HW structure
+ *
+ *  This uses a trial and error method to loop through possible PHY
+ *  addresses. It tests each by reading the PHY ID registers and
+ *  checking for a match.
+ **/
+s32 e1000e_determine_phy_address(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_PHY_TYPE;
+	u32 phy_addr= 0;
+	u32 i = 0;
+	enum e1000_phy_type phy_type = e1000_phy_unknown;
+
+	do {
+		for (phy_addr = 0; phy_addr < 4; phy_addr++) {
+			hw->phy.addr = phy_addr;
+			e1000e_get_phy_id(hw);
+			phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
+
+			/* 
+			 * If phy_type is valid, break - we found our
+			 * PHY address
+			 */
+			if (phy_type  != e1000_phy_unknown) {
+				ret_val = 0;
+				break;
+			}
+		}
+		i++;
+	} while ((ret_val != 0) && (i < 100));
+
+	return ret_val;
+}
+
+/**
+ *  e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
+ *  @page: page to access
+ *
+ *  Returns the phy address for the page requested.
+ **/
+static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
+{
+	u32 phy_addr = 2;
+
+	if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
+		phy_addr = 1;
+
+	return phy_addr;
+}
+
+/**
+ *  e1000e_write_phy_reg_bm - Write BM PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquires semaphore, if necessary, then writes the data to PHY register
+ *  at the offset.  Release any acquired semaphores before exiting.
+ **/
+s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
+{
+	s32 ret_val;
+	u32 page_select = 0;
+	u32 page = offset >> IGP_PAGE_SHIFT;
+	u32 page_shift = 0;
+
+	/* Page 800 works differently than the rest so it has its own func */
+	if (page == BM_WUC_PAGE) {
+		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
+							 false);
+		goto out;
+	}
+
+	ret_val = hw->phy.ops.acquire_phy(hw);
+	if (ret_val)
+		goto out;
+
+	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
+
+	if (offset > MAX_PHY_MULTI_PAGE_REG) {
+		/*
+		 * Page select is register 31 for phy address 1 and 22 for
+		 * phy address 2 and 3. Page select is shifted only for
+		 * phy address 1.
+		 */
+		if (hw->phy.addr == 1) {
+			page_shift = IGP_PAGE_SHIFT;
+			page_select = IGP01E1000_PHY_PAGE_SELECT;
+		} else {
+			page_shift = 0;
+			page_select = BM_PHY_PAGE_SELECT;
+		}
+
+		/* Page is shifted left, PHY expects (page x 32) */
+		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
+		                                    (page << page_shift));
+		if (ret_val) {
+			hw->phy.ops.release_phy(hw);
+			goto out;
+		}
+	}
+
+	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+	                                    data);
+
+	hw->phy.ops.release_phy(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000e_read_phy_reg_bm - Read BM PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquires semaphore, if necessary, then reads the PHY register at offset
+ *  and storing the retrieved information in data.  Release any acquired
+ *  semaphores before exiting.
+ **/
+s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+	s32 ret_val;
+	u32 page_select = 0;
+	u32 page = offset >> IGP_PAGE_SHIFT;
+	u32 page_shift = 0;
+
+	/* Page 800 works differently than the rest so it has its own func */
+	if (page == BM_WUC_PAGE) {
+		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
+							 true);
+		goto out;
+	}
+
+	ret_val = hw->phy.ops.acquire_phy(hw);
+	if (ret_val)
+		goto out;
+
+	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
+
+	if (offset > MAX_PHY_MULTI_PAGE_REG) {
+		/*
+		 * Page select is register 31 for phy address 1 and 22 for
+		 * phy address 2 and 3. Page select is shifted only for
+		 * phy address 1.
+		 */
+		if (hw->phy.addr == 1) {
+			page_shift = IGP_PAGE_SHIFT;
+			page_select = IGP01E1000_PHY_PAGE_SELECT;
+		} else {
+			page_shift = 0;
+			page_select = BM_PHY_PAGE_SELECT;
+		}
+
+		/* Page is shifted left, PHY expects (page x 32) */
+		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
+		                                    (page << page_shift));
+		if (ret_val) {
+			hw->phy.ops.release_phy(hw);
+			goto out;
+		}
+	}
+
+	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+	                                   data);
+	hw->phy.ops.release_phy(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read or written
+ *  @data: pointer to the data to read or write
+ *  @read: determines if operation is read or write
+ *
+ *  Acquires semaphore, if necessary, then reads the PHY register at offset
+ *  and storing the retrieved information in data.  Release any acquired
+ *  semaphores before exiting. Note that procedure to read the wakeup
+ *  registers are different. It works as such:
+ *  1) Set page 769, register 17, bit 2 = 1
+ *  2) Set page to 800 for host (801 if we were manageability)
+ *  3) Write the address using the address opcode (0x11)
+ *  4) Read or write the data using the data opcode (0x12)
+ *  5) Restore 769_17.2 to its original value
+ **/
+static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
+					  u16 *data, bool read)
+{
+	s32 ret_val;
+	u16 reg = ((u16)offset) & PHY_REG_MASK;
+	u16 phy_reg = 0;
+	u8  phy_acquired = 1;
+
+
+	ret_val = hw->phy.ops.acquire_phy(hw);
+	if (ret_val) {
+		phy_acquired = 0;
+		goto out;
+	}
+
+	/* All operations in this function are phy address 1 */
+	hw->phy.addr = 1;
+
+	/* Set page 769 */
+	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+
+	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
+	if (ret_val)
+		goto out;
+
+	/* First clear bit 4 to avoid a power state change */
+	phy_reg &= ~(BM_WUC_HOST_WU_BIT);
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+	if (ret_val)
+		goto out;
+
+	/* Write bit 2 = 1, and clear bit 4 to 769_17 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
+	                                    phy_reg | BM_WUC_ENABLE_BIT);
+	if (ret_val)
+		goto out;
+
+	/* Select page 800 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+	                                    (BM_WUC_PAGE << IGP_PAGE_SHIFT));
+
+	/* Write the page 800 offset value using opcode 0x11 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
+	if (ret_val)
+		goto out;
+
+	if (read) {
+	        /* Read the page 800 value using opcode 0x12 */
+		ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
+		                                   data);
+	} else {
+	        /* Read the page 800 value using opcode 0x12 */
+		ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
+						    *data);
+	}
+
+	if (ret_val)
+		goto out;
+
+	/*
+	 * Restore 769_17.2 to its original value
+	 * Set page 769
+	 */
+	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+
+	/* Clear 769_17.2 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+
+out:
+	if (phy_acquired == 1)
+		hw->phy.ops.release_phy(hw);
+	return ret_val;
+}
+
+/**
  *  e1000e_commit_phy - Soft PHY reset
  *  @hw: pointer to the HW structure
  *
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 2eb82ab..795c594 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -202,7 +202,7 @@
 	0x0000,Cmd_MCast,
 	0x0076,                 /* link to next command */
 #define CONF_NR_MULTICAST 0x44
-	0x0000,                 /* number of multicast addresses */
+	0x0000,                 /* number of bytes in multicast address(es) */
 #define CONF_MULTICAST 0x46
 	0x0000, 0x0000, 0x0000, /* some addresses */
 	0x0000, 0x0000, 0x0000,
@@ -1569,7 +1569,7 @@
 
 static void eexp_setup_filter(struct net_device *dev)
 {
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	unsigned short ioaddr = dev->base_addr;
 	int count = dev->mc_count;
 	int i;
@@ -1580,9 +1580,9 @@
 	}
 
 	outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
-	outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST));
-	for (i = 0; i < count; i++) {
-		unsigned short *data = (unsigned short *)dmi->dmi_addr;
+	outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST));
+	for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) {
+		unsigned short *data;
 		if (!dmi) {
 			printk(KERN_INFO "%s: too few multicast addresses\n", dev->name);
 			break;
@@ -1591,6 +1591,7 @@
 			printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
 			continue;
 		}
+		data = (unsigned short *)dmi->dmi_addr;
 		outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
 		outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
 		outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index f5dacce..fe872fb 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0090"
+#define DRV_VERSION	"EHEA_0091"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
@@ -118,6 +118,13 @@
 #define EHEA_MR_ACC_CTRL       0x00800000
 
 #define EHEA_BUSMAP_START      0x8000000000000000ULL
+#define EHEA_INVAL_ADDR        0xFFFFFFFFFFFFFFFFULL
+#define EHEA_DIR_INDEX_SHIFT 13                   /* 8k Entries in 64k block */
+#define EHEA_TOP_INDEX_SHIFT (EHEA_DIR_INDEX_SHIFT * 2)
+#define EHEA_MAP_ENTRIES (1 << EHEA_DIR_INDEX_SHIFT)
+#define EHEA_MAP_SIZE (0x10000)                   /* currently fixed map size */
+#define EHEA_INDEX_MASK (EHEA_MAP_ENTRIES - 1)
+
 
 #define EHEA_WATCH_DOG_TIMEOUT 10*HZ
 
@@ -192,10 +199,20 @@
 				   set to 0 if unused */
 };
 
-struct ehea_busmap {
-	unsigned int entries;		/* total number of entries */
-	unsigned int valid_sections;	/* number of valid sections */
-	u64 *vaddr;
+/*
+ * Memory map data structures
+ */
+struct ehea_dir_bmap
+{
+	u64 ent[EHEA_MAP_ENTRIES];
+};
+struct ehea_top_bmap
+{
+	struct ehea_dir_bmap *dir[EHEA_MAP_ENTRIES];
+};
+struct ehea_bmap
+{
+	struct ehea_top_bmap *top[EHEA_MAP_ENTRIES];
 };
 
 struct ehea_qp;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index f9bc21c..d1b6d4e 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -35,6 +35,7 @@
 #include <linux/if_ether.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <linux/memory.h>
 #include <asm/kexec.h>
 #include <linux/mutex.h>
 
@@ -3503,6 +3504,24 @@
 					      0, H_DEREG_BCMC);
 }
 
+static int ehea_mem_notifier(struct notifier_block *nb,
+                             unsigned long action, void *data)
+{
+	switch (action) {
+	case MEM_OFFLINE:
+		ehea_info("memory has been removed");
+		ehea_rereg_mrs(NULL);
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block ehea_mem_nb = {
+	.notifier_call = ehea_mem_notifier,
+};
+
 static int ehea_reboot_notifier(struct notifier_block *nb,
 				unsigned long action, void *unused)
 {
@@ -3581,6 +3600,10 @@
 	if (ret)
 		ehea_info("failed registering reboot notifier");
 
+	ret = register_memory_notifier(&ehea_mem_nb);
+	if (ret)
+		ehea_info("failed registering memory remove notifier");
+
 	ret = crash_shutdown_register(&ehea_crash_handler);
 	if (ret)
 		ehea_info("failed registering crash handler");
@@ -3604,6 +3627,7 @@
 out3:
 	ibmebus_unregister_driver(&ehea_driver);
 out2:
+	unregister_memory_notifier(&ehea_mem_nb);
 	unregister_reboot_notifier(&ehea_reboot_nb);
 	crash_shutdown_unregister(&ehea_crash_handler);
 out:
@@ -3621,6 +3645,7 @@
 	ret = crash_shutdown_unregister(&ehea_crash_handler);
 	if (ret)
 		ehea_info("failed unregistering crash handler");
+	unregister_memory_notifier(&ehea_mem_nb);
 	kfree(ehea_fw_handles.arr);
 	kfree(ehea_bcmc_regs.arr);
 	ehea_destroy_busmap();
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index d522e90..140f05b 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -31,8 +31,8 @@
 #include "ehea_phyp.h"
 #include "ehea_qmr.h"
 
+struct ehea_bmap *ehea_bmap = NULL;
 
-struct ehea_busmap ehea_bmap = { 0, 0, NULL };
 
 
 static void *hw_qpageit_get_inc(struct hw_queue *queue)
@@ -559,125 +559,253 @@
 	return 0;
 }
 
-int ehea_create_busmap(void)
+static inline int ehea_calc_index(unsigned long i, unsigned long s)
 {
-	u64 vaddr = EHEA_BUSMAP_START;
-	unsigned long high_section_index = 0;
-	int i;
+	return (i >> s) & EHEA_INDEX_MASK;
+}
 
-	/*
-	 * Sections are not in ascending order -> Loop over all sections and
-	 * find the highest PFN to compute the required map size.
-	*/
-	ehea_bmap.valid_sections = 0;
+static inline int ehea_init_top_bmap(struct ehea_top_bmap *ehea_top_bmap,
+				     int dir)
+{
+	if(!ehea_top_bmap->dir[dir]) {
+		ehea_top_bmap->dir[dir] =
+			kzalloc(sizeof(struct ehea_dir_bmap), GFP_KERNEL);
+		if (!ehea_top_bmap->dir[dir])
+			return -ENOMEM;
+	}
+	return 0;
+}
 
-	for (i = 0; i < NR_MEM_SECTIONS; i++)
-		if (valid_section_nr(i))
-			high_section_index = i;
+static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir)
+{
+	if(!ehea_bmap->top[top]) {
+		ehea_bmap->top[top] =
+			kzalloc(sizeof(struct ehea_top_bmap), GFP_KERNEL);
+		if (!ehea_bmap->top[top])
+			return -ENOMEM;
+	}
+	return ehea_init_top_bmap(ehea_bmap->top[top], dir);
+}
 
-	ehea_bmap.entries = high_section_index + 1;
-	ehea_bmap.vaddr = vmalloc(ehea_bmap.entries * sizeof(*ehea_bmap.vaddr));
+static int ehea_create_busmap_callback(unsigned long pfn,
+				       unsigned long nr_pages, void *arg)
+{
+	unsigned long i, mr_len, start_section, end_section;
+	start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
+	end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
+	mr_len = *(unsigned long *)arg;
 
-	if (!ehea_bmap.vaddr)
+	ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
+	if (!ehea_bmap)
 		return -ENOMEM;
 
-	for (i = 0 ; i < ehea_bmap.entries; i++) {
-		unsigned long pfn = section_nr_to_pfn(i);
+	for (i = start_section; i < end_section; i++) {
+		int ret;
+		int top, dir, idx;
+		u64 vaddr;
 
-		if (pfn_valid(pfn)) {
-			ehea_bmap.vaddr[i] = vaddr;
-			vaddr += EHEA_SECTSIZE;
-			ehea_bmap.valid_sections++;
-		} else
-			ehea_bmap.vaddr[i] = 0;
+		top = ehea_calc_index(i, EHEA_TOP_INDEX_SHIFT);
+		dir = ehea_calc_index(i, EHEA_DIR_INDEX_SHIFT);
+
+		ret = ehea_init_bmap(ehea_bmap, top, dir);
+		if(ret)
+			return ret;
+
+		idx = i & EHEA_INDEX_MASK;
+		vaddr = EHEA_BUSMAP_START + mr_len + i * EHEA_SECTSIZE;
+
+		ehea_bmap->top[top]->dir[dir]->ent[idx] = vaddr;
 	}
 
+	mr_len += nr_pages * PAGE_SIZE;
+	*(unsigned long *)arg = mr_len;
+
 	return 0;
 }
 
+static unsigned long ehea_mr_len;
+
+static DEFINE_MUTEX(ehea_busmap_mutex);
+
+int ehea_create_busmap(void)
+{
+	int ret;
+	mutex_lock(&ehea_busmap_mutex);
+	ehea_mr_len = 0;
+	ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, &ehea_mr_len,
+				   ehea_create_busmap_callback);
+	mutex_unlock(&ehea_busmap_mutex);
+	return ret;
+}
+
 void ehea_destroy_busmap(void)
 {
-	vfree(ehea_bmap.vaddr);
+	int top, dir;
+	mutex_lock(&ehea_busmap_mutex);
+	if (!ehea_bmap)
+		goto out_destroy;
+
+	for (top = 0; top < EHEA_MAP_ENTRIES; top++) {
+		if (!ehea_bmap->top[top])
+			continue;
+
+		for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) {
+			if (!ehea_bmap->top[top]->dir[dir])
+				continue;
+
+			kfree(ehea_bmap->top[top]->dir[dir]);
+		}
+
+		kfree(ehea_bmap->top[top]);
+	}
+
+	kfree(ehea_bmap);
+	ehea_bmap = NULL;
+out_destroy:	
+	mutex_unlock(&ehea_busmap_mutex);
 }
 
 u64 ehea_map_vaddr(void *caddr)
 {
-	u64 mapped_addr;
-	unsigned long index = __pa(caddr) >> SECTION_SIZE_BITS;
+	int top, dir, idx;
+	unsigned long index, offset;
 
-	if (likely(index < ehea_bmap.entries)) {
-		mapped_addr = ehea_bmap.vaddr[index];
-		if (likely(mapped_addr))
-			mapped_addr |= (((unsigned long)caddr)
-					& (EHEA_SECTSIZE - 1));
-		else
-			mapped_addr = -1;
-	} else
-		mapped_addr = -1;
+	if (!ehea_bmap)
+		return EHEA_INVAL_ADDR;
 
-	if (unlikely(mapped_addr == -1))
-		if (!test_and_set_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
-			schedule_work(&ehea_rereg_mr_task);
+	index = virt_to_abs(caddr) >> SECTION_SIZE_BITS;
+	top = (index >> EHEA_TOP_INDEX_SHIFT) & EHEA_INDEX_MASK;
+	if (!ehea_bmap->top[top])
+		return EHEA_INVAL_ADDR;
 
-	return mapped_addr;
+	dir = (index >> EHEA_DIR_INDEX_SHIFT) & EHEA_INDEX_MASK;
+	if (!ehea_bmap->top[top]->dir[dir])
+		return EHEA_INVAL_ADDR;
+
+	idx = index & EHEA_INDEX_MASK;
+	if (!ehea_bmap->top[top]->dir[dir]->ent[idx])
+		return EHEA_INVAL_ADDR;
+
+	offset = (unsigned long)caddr & (EHEA_SECTSIZE - 1);
+	return ehea_bmap->top[top]->dir[dir]->ent[idx] | offset;
+}
+
+static inline void *ehea_calc_sectbase(int top, int dir, int idx)
+{
+	unsigned long ret = idx;
+	ret |= dir << EHEA_DIR_INDEX_SHIFT;
+	ret |= top << EHEA_TOP_INDEX_SHIFT;
+	return abs_to_virt(ret << SECTION_SIZE_BITS);
+}
+
+static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt,
+			       struct ehea_adapter *adapter,
+			       struct ehea_mr *mr)
+{
+	void *pg;
+	u64 j, m, hret;
+	unsigned long k = 0;
+	u64 pt_abs = virt_to_abs(pt);
+
+	void *sectbase = ehea_calc_sectbase(top, dir, idx);
+
+	for (j = 0; j < (EHEA_PAGES_PER_SECTION / EHEA_MAX_RPAGE); j++) {
+
+		for (m = 0; m < EHEA_MAX_RPAGE; m++) {
+			pg = sectbase + ((k++) * EHEA_PAGESIZE);
+			pt[m] = virt_to_abs(pg);
+		}
+		hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0,
+						0, pt_abs, EHEA_MAX_RPAGE);
+
+		if ((hret != H_SUCCESS)
+		    && (hret != H_PAGE_REGISTERED)) {
+			ehea_h_free_resource(adapter->handle, mr->handle,
+					     FORCE_FREE);
+			ehea_error("register_rpage_mr failed");
+			return hret;
+		}
+	}
+	return hret;
+}
+
+static u64 ehea_reg_mr_sections(int top, int dir, u64 *pt,
+				struct ehea_adapter *adapter,
+				struct ehea_mr *mr)
+{
+	u64 hret = H_SUCCESS;
+	int idx;
+
+	for (idx = 0; idx < EHEA_MAP_ENTRIES; idx++) {
+		if (!ehea_bmap->top[top]->dir[dir]->ent[idx])
+			continue;
+		
+		hret = ehea_reg_mr_section(top, dir, idx, pt, adapter, mr);
+		if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
+			    	return hret;
+	}
+	return hret;
+}
+
+static u64 ehea_reg_mr_dir_sections(int top, u64 *pt,
+				    struct ehea_adapter *adapter,
+				    struct ehea_mr *mr)
+{
+	u64 hret = H_SUCCESS;
+	int dir;
+
+	for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) {
+		if (!ehea_bmap->top[top]->dir[dir])
+			continue;
+
+		hret = ehea_reg_mr_sections(top, dir, pt, adapter, mr);
+		if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
+			    	return hret;
+	}
+	return hret;
 }
 
 int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
 {
 	int ret;
 	u64 *pt;
-	void *pg;
-	u64 hret, pt_abs, i, j, m, mr_len;
+	u64 hret;
 	u32 acc_ctrl = EHEA_MR_ACC_CTRL;
 
-	mr_len = ehea_bmap.valid_sections * EHEA_SECTSIZE;
+	unsigned long top;
 
-	pt =  kzalloc(PAGE_SIZE, GFP_KERNEL);
+	pt = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!pt) {
 		ehea_error("no mem");
 		ret = -ENOMEM;
 		goto out;
 	}
-	pt_abs = virt_to_abs(pt);
 
-	hret = ehea_h_alloc_resource_mr(adapter->handle,
-					EHEA_BUSMAP_START, mr_len,
-					acc_ctrl, adapter->pd,
+	hret = ehea_h_alloc_resource_mr(adapter->handle, EHEA_BUSMAP_START,
+					ehea_mr_len, acc_ctrl, adapter->pd,
 					&mr->handle, &mr->lkey);
+
 	if (hret != H_SUCCESS) {
 		ehea_error("alloc_resource_mr failed");
 		ret = -EIO;
 		goto out;
 	}
 
-	for (i = 0 ; i < ehea_bmap.entries; i++)
-		if (ehea_bmap.vaddr[i]) {
-			void *sectbase = __va(i << SECTION_SIZE_BITS);
-			unsigned long k = 0;
+	if (!ehea_bmap) {
+		ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE);
+		ehea_error("no busmap available");
+		ret = -EIO;
+		goto out;
+	}
 
-			for (j = 0; j < (EHEA_PAGES_PER_SECTION /
-					 EHEA_MAX_RPAGE); j++) {
+	for (top = 0; top < EHEA_MAP_ENTRIES; top++) {
+		if (!ehea_bmap->top[top])
+			continue;
 
-				for (m = 0; m < EHEA_MAX_RPAGE; m++) {
-					pg = sectbase + ((k++) * EHEA_PAGESIZE);
-					pt[m] = virt_to_abs(pg);
-				}
-
-				hret = ehea_h_register_rpage_mr(adapter->handle,
-								mr->handle,
-								0, 0, pt_abs,
-								EHEA_MAX_RPAGE);
-				if ((hret != H_SUCCESS)
-				    && (hret != H_PAGE_REGISTERED)) {
-					ehea_h_free_resource(adapter->handle,
-							     mr->handle,
-							     FORCE_FREE);
-					ehea_error("register_rpage_mr failed");
-					ret = -EIO;
-					goto out;
-				}
-			}
-		}
+		hret = ehea_reg_mr_dir_sections(top, pt, adapter, mr);
+		if((hret != H_PAGE_REGISTERED) && (hret != H_SUCCESS))
+			break;
+	}
 
 	if (hret != H_SUCCESS) {
 		ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE);
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index ba75efc..f0014cf 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -194,7 +194,7 @@
 
 	ret = of_address_to_resource(ofdev->node, 0, &res);
 	if (ret)
-		return ret;
+		goto out_res;
 
 	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
 
@@ -236,6 +236,7 @@
 	kfree(new_bus->irq);
 out_unmap_regs:
 	iounmap(fec->fecp);
+out_res:
 out_fec:
 	kfree(fec);
 out_mii:
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 642dc63..393a0f1 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -138,6 +138,7 @@
 static void gfar_netpoll(struct net_device *dev);
 #endif
 int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+static int gfar_clean_tx_ring(struct net_device *dev);
 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
 static void gfar_vlan_rx_register(struct net_device *netdev,
 		                struct vlan_group *grp);
@@ -634,6 +635,8 @@
 			dev_kfree_skb_any(priv->tx_skbuff[i]);
 			priv->tx_skbuff[i] = NULL;
 		}
+
+		txbdp++;
 	}
 
 	kfree(priv->tx_skbuff);
@@ -1141,7 +1144,7 @@
 }
 
 /* Changes the mac address if the controller is not running. */
-int gfar_set_mac_address(struct net_device *dev)
+static int gfar_set_mac_address(struct net_device *dev)
 {
 	gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
 
@@ -1260,7 +1263,7 @@
 }
 
 /* Interrupt Handler for Transmit complete */
-int gfar_clean_tx_ring(struct net_device *dev)
+static int gfar_clean_tx_ring(struct net_device *dev)
 {
 	struct txbd8 *bdp;
 	struct gfar_private *priv = netdev_priv(dev);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index fd487be..27f37c8 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -782,5 +782,8 @@
 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
 		int enable, u32 regnum, u32 read);
 void gfar_init_sysfs(struct net_device *dev);
+int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
+			  int regnum, u16 value);
+int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
 
 #endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 230878b..5116f68 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -103,10 +103,10 @@
 
 	spin_lock_irqsave(&priv->rxlock, flags);
 	if (length > priv->rx_buffer_size)
-		return count;
+		goto out;
 
 	if (length == priv->rx_stash_size)
-		return count;
+		goto out;
 
 	priv->rx_stash_size = length;
 
@@ -125,6 +125,7 @@
 
 	gfar_write(&priv->regs->attr, temp);
 
+out:
 	spin_unlock_irqrestore(&priv->rxlock, flags);
 
 	return count;
@@ -154,10 +155,10 @@
 
 	spin_lock_irqsave(&priv->rxlock, flags);
 	if (index > priv->rx_stash_size)
-		return count;
+		goto out;
 
 	if (index == priv->rx_stash_index)
-		return count;
+		goto out;
 
 	priv->rx_stash_index = index;
 
@@ -166,6 +167,7 @@
 	temp |= ATTRELI_EI(index);
 	gfar_write(&priv->regs->attreli, flags);
 
+out:
 	spin_unlock_irqrestore(&priv->rxlock, flags);
 
 	return count;
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index a873d2b..a7714da 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -100,7 +100,9 @@
 static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info);
+#ifdef CONFIG_PNP
 static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id);
+#endif
 
 /* These are the known NSC chips */
 static nsc_chip_t chips[] = {
@@ -156,9 +158,11 @@
 MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table);
 
 static struct pnp_driver nsc_ircc_pnp_driver = {
+#ifdef CONFIG_PNP
 	.name = "nsc-ircc",
 	.id_table = nsc_ircc_pnp_table,
 	.probe = nsc_ircc_pnp_probe,
+#endif
 };
 
 /* Some prototypes */
@@ -916,6 +920,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PNP
 /* PNP probing */
 static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id)
 {
@@ -952,6 +957,7 @@
 
 	return 0;
 }
+#endif
 
 /*
  * Function nsc_ircc_setup (info)
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 1f26da7..cfe0194 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -376,6 +376,7 @@
 
 static int pnp_driver_registered;
 
+#ifdef CONFIG_PNP
 static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev,
 				      const struct pnp_device_id *dev_id)
 {
@@ -402,7 +403,9 @@
 	.id_table	= smsc_ircc_pnp_table,
 	.probe		= smsc_ircc_pnp_probe,
 };
-
+#else /* CONFIG_PNP */
+static struct pnp_driver smsc_ircc_pnp_driver;
+#endif
 
 /*******************************************************************************
  *
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 2056cfc..c36a03a 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -450,7 +450,7 @@
 	unregister_netdevice(dev);
 
 	if (list_empty(&port->vlans))
-		macvlan_port_destroy(dev);
+		macvlan_port_destroy(port->dev);
 }
 
 static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index cb46446..03a9abc 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -551,7 +551,7 @@
 	u64 mtt_seg;
 	int err = -ENOMEM;
 
-	if (page_shift < 12 || page_shift >= 32)
+	if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32)
 		return -EINVAL;
 
 	/* All MTTs must fit in the same page */
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 381b36e..b7915cd 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -91,6 +91,11 @@
  */
 #define PHY_ADDR_REG				0x0000
 #define SMI_REG					0x0004
+#define WINDOW_BASE(i)				(0x0200 + ((i) << 3))
+#define WINDOW_SIZE(i)				(0x0204 + ((i) << 3))
+#define WINDOW_REMAP_HIGH(i)			(0x0280 + ((i) << 2))
+#define WINDOW_BAR_ENABLE			0x0290
+#define WINDOW_PROTECT(i)			(0x0294 + ((i) << 4))
 
 /*
  * Per-port registers.
@@ -507,9 +512,23 @@
 	u32 late_collision;
 };
 
+struct mv643xx_shared_private {
+	void __iomem *eth_base;
+
+	/* used to protect SMI_REG, which is shared across ports */
+	spinlock_t phy_lock;
+
+	u32 win_protect;
+
+	unsigned int t_clk;
+};
+
 struct mv643xx_private {
+	struct mv643xx_shared_private *shared;
 	int port_num;			/* User Ethernet port number	*/
 
+	struct mv643xx_shared_private *shared_smi;
+
 	u32 rx_sram_addr;		/* Base address of rx sram area */
 	u32 rx_sram_size;		/* Size of rx sram area		*/
 	u32 tx_sram_addr;		/* Base address of tx sram area */
@@ -614,19 +633,14 @@
 static char mv643xx_driver_name[] = "mv643xx_eth";
 static char mv643xx_driver_version[] = "1.0";
 
-static void __iomem *mv643xx_eth_base;
-
-/* used to protect SMI_REG, which is shared across ports */
-static DEFINE_SPINLOCK(mv643xx_eth_phy_lock);
-
 static inline u32 rdl(struct mv643xx_private *mp, int offset)
 {
-	return readl(mv643xx_eth_base + offset);
+	return readl(mp->shared->eth_base + offset);
 }
 
 static inline void wrl(struct mv643xx_private *mp, int offset, u32 data)
 {
-	writel(data, mv643xx_eth_base + offset);
+	writel(data, mp->shared->eth_base + offset);
 }
 
 /*
@@ -1119,7 +1133,6 @@
  *
  * INPUT:
  *	struct mv643xx_private *mp	Ethernet port
- *	unsigned int t_clk		t_clk of the MV-643xx chip in HZ units
  *	unsigned int delay		Delay in usec
  *
  * OUTPUT:
@@ -1130,10 +1143,10 @@
  *
  */
 static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp,
-					unsigned int t_clk, unsigned int delay)
+					unsigned int delay)
 {
 	unsigned int port_num = mp->port_num;
-	unsigned int coal = ((t_clk / 1000000) * delay) / 64;
+	unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
 
 	/* Set RX Coalescing mechanism */
 	wrl(mp, SDMA_CONFIG_REG(port_num),
@@ -1158,7 +1171,6 @@
  *
  * INPUT:
  *	struct mv643xx_private *mp	Ethernet port
- *	unsigned int t_clk		t_clk of the MV-643xx chip in HZ units
  *	unsigned int delay		Delay in uSeconds
  *
  * OUTPUT:
@@ -1169,9 +1181,9 @@
  *
  */
 static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp,
-					unsigned int t_clk, unsigned int delay)
+					unsigned int delay)
 {
-	unsigned int coal = ((t_clk / 1000000) * delay) / 64;
+	unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
 
 	/* Set TX Coalescing mechanism */
 	wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4);
@@ -1413,11 +1425,11 @@
 
 #ifdef MV643XX_COAL
 	mp->rx_int_coal =
-		eth_port_set_rx_coal(mp, 133000000, MV643XX_RX_COAL);
+		eth_port_set_rx_coal(mp, MV643XX_RX_COAL);
 #endif
 
 	mp->tx_int_coal =
-		eth_port_set_tx_coal(mp, 133000000, MV643XX_TX_COAL);
+		eth_port_set_tx_coal(mp, MV643XX_TX_COAL);
 
 	/* Unmask phy and link status changes interrupts */
 	wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT);
@@ -1827,6 +1839,11 @@
 		return -ENODEV;
 	}
 
+	if (pd->shared == NULL) {
+		printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n");
+		return -ENODEV;
+	}
+
 	dev = alloc_etherdev(sizeof(struct mv643xx_private));
 	if (!dev)
 		return -ENOMEM;
@@ -1877,8 +1894,16 @@
 
 	spin_lock_init(&mp->lock);
 
+	mp->shared = platform_get_drvdata(pd->shared);
 	port_num = mp->port_num = pd->port_number;
 
+	if (mp->shared->win_protect)
+		wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect);
+
+	mp->shared_smi = mp->shared;
+	if (pd->shared_smi != NULL)
+		mp->shared_smi = platform_get_drvdata(pd->shared_smi);
+
 	/* set default config values */
 	eth_port_uc_addr_get(mp, dev->dev_addr);
 	mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
@@ -1983,30 +2008,91 @@
 	return 0;
 }
 
+static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp,
+					  struct mbus_dram_target_info *dram)
+{
+	void __iomem *base = msp->eth_base;
+	u32 win_enable;
+	u32 win_protect;
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		writel(0, base + WINDOW_BASE(i));
+		writel(0, base + WINDOW_SIZE(i));
+		if (i < 4)
+			writel(0, base + WINDOW_REMAP_HIGH(i));
+	}
+
+	win_enable = 0x3f;
+	win_protect = 0;
+
+	for (i = 0; i < dram->num_cs; i++) {
+		struct mbus_dram_window *cs = dram->cs + i;
+
+		writel((cs->base & 0xffff0000) |
+			(cs->mbus_attr << 8) |
+			dram->mbus_dram_target_id, base + WINDOW_BASE(i));
+		writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i));
+
+		win_enable &= ~(1 << i);
+		win_protect |= 3 << (2 * i);
+	}
+
+	writel(win_enable, base + WINDOW_BAR_ENABLE);
+	msp->win_protect = win_protect;
+}
+
 static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 {
 	static int mv643xx_version_printed = 0;
+	struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
+	struct mv643xx_shared_private *msp;
 	struct resource *res;
+	int ret;
 
 	if (!mv643xx_version_printed++)
 		printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
 
+	ret = -EINVAL;
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL)
-		return -ENODEV;
+		goto out;
 
-	mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1);
-	if (mv643xx_eth_base == NULL)
-		return -ENOMEM;
+	ret = -ENOMEM;
+	msp = kmalloc(sizeof(*msp), GFP_KERNEL);
+	if (msp == NULL)
+		goto out;
+	memset(msp, 0, sizeof(*msp));
+
+	msp->eth_base = ioremap(res->start, res->end - res->start + 1);
+	if (msp->eth_base == NULL)
+		goto out_free;
+
+	spin_lock_init(&msp->phy_lock);
+	msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000;
+
+	platform_set_drvdata(pdev, msp);
+
+	/*
+	 * (Re-)program MBUS remapping windows if we are asked to.
+	 */
+	if (pd != NULL && pd->dram != NULL)
+		mv643xx_eth_conf_mbus_windows(msp, pd->dram);
 
 	return 0;
 
+out_free:
+	kfree(msp);
+out:
+	return ret;
 }
 
 static int mv643xx_eth_shared_remove(struct platform_device *pdev)
 {
-	iounmap(mv643xx_eth_base);
-	mv643xx_eth_base = NULL;
+	struct mv643xx_shared_private *msp = platform_get_drvdata(pdev);
+
+	iounmap(msp->eth_base);
+	kfree(msp);
 
 	return 0;
 }
@@ -2906,15 +2992,16 @@
 static void eth_port_read_smi_reg(struct mv643xx_private *mp,
 				unsigned int phy_reg, unsigned int *value)
 {
+	void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG;
 	int phy_addr = ethernet_phy_get(mp);
 	unsigned long flags;
 	int i;
 
 	/* the SMI register is a shared resource */
-	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
+	spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
 
 	/* wait for the SMI register to become available */
-	for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) {
+	for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("%s: PHY busy timeout\n", mp->dev->name);
 			goto out;
@@ -2922,11 +3009,11 @@
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	wrl(mp, SMI_REG,
-		(phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ);
+	writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ,
+		smi_reg);
 
 	/* now wait for the data to be valid */
-	for (i = 0; !(rdl(mp, SMI_REG) & ETH_SMI_READ_VALID); i++) {
+	for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("%s: PHY read timeout\n", mp->dev->name);
 			goto out;
@@ -2934,9 +3021,9 @@
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	*value = rdl(mp, SMI_REG) & 0xffff;
+	*value = readl(smi_reg) & 0xffff;
 out:
-	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
+	spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
 }
 
 /*
@@ -2962,17 +3049,16 @@
 static void eth_port_write_smi_reg(struct mv643xx_private *mp,
 				   unsigned int phy_reg, unsigned int value)
 {
-	int phy_addr;
-	int i;
+	void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG;
+	int phy_addr = ethernet_phy_get(mp);
 	unsigned long flags;
-
-	phy_addr = ethernet_phy_get(mp);
+	int i;
 
 	/* the SMI register is a shared resource */
-	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
+	spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
 
 	/* wait for the SMI register to become available */
-	for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) {
+	for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("%s: PHY busy timeout\n", mp->dev->name);
 			goto out;
@@ -2980,10 +3066,10 @@
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) |
-				ETH_SMI_OPCODE_WRITE | (value & 0xffff));
+	writel((phy_addr << 16) | (phy_reg << 21) |
+		ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg);
 out:
-	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
+	spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
 }
 
 /*
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index ef63c8d..c91b12e 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -144,11 +144,13 @@
 	char *req_bytes;
 	struct myri10ge_tx_buffer_state *info;
 	int mask;		/* number of transmit slots -1  */
-	int boundary;		/* boundary transmits cannot cross */
 	int req ____cacheline_aligned;	/* transmit slots submitted     */
 	int pkt_start;		/* packets started */
+	int stop_queue;
+	int linearized;
 	int done ____cacheline_aligned;	/* transmit slots completed     */
 	int pkt_done;		/* packets completed */
+	int wake_queue;
 };
 
 struct myri10ge_rx_done {
@@ -160,29 +162,50 @@
 	struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS];
 };
 
-struct myri10ge_priv {
-	int running;		/* running?             */
-	int csum_flag;		/* rx_csums?            */
+struct myri10ge_slice_netstats {
+	unsigned long rx_packets;
+	unsigned long tx_packets;
+	unsigned long rx_bytes;
+	unsigned long tx_bytes;
+	unsigned long rx_dropped;
+	unsigned long tx_dropped;
+};
+
+struct myri10ge_slice_state {
 	struct myri10ge_tx_buf tx;	/* transmit ring        */
 	struct myri10ge_rx_buf rx_small;
 	struct myri10ge_rx_buf rx_big;
 	struct myri10ge_rx_done rx_done;
-	int small_bytes;
-	int big_bytes;
 	struct net_device *dev;
 	struct napi_struct napi;
+	struct myri10ge_priv *mgp;
+	struct myri10ge_slice_netstats stats;
+	__be32 __iomem *irq_claim;
+	struct mcp_irq_data *fw_stats;
+	dma_addr_t fw_stats_bus;
+	int watchdog_tx_done;
+	int watchdog_tx_req;
+};
+
+struct myri10ge_priv {
+	struct myri10ge_slice_state ss;
+	int tx_boundary;	/* boundary transmits cannot cross */
+	int running;		/* running?             */
+	int csum_flag;		/* rx_csums?            */
+	int small_bytes;
+	int big_bytes;
+	int max_intr_slots;
+	struct net_device *dev;
 	struct net_device_stats stats;
+	spinlock_t stats_lock;
 	u8 __iomem *sram;
 	int sram_size;
 	unsigned long board_span;
 	unsigned long iomem_base;
-	__be32 __iomem *irq_claim;
 	__be32 __iomem *irq_deassert;
 	char *mac_addr_string;
 	struct mcp_cmd_response *cmd;
 	dma_addr_t cmd_bus;
-	struct mcp_irq_data *fw_stats;
-	dma_addr_t fw_stats_bus;
 	struct pci_dev *pdev;
 	int msi_enabled;
 	u32 link_state;
@@ -191,20 +214,16 @@
 	__be32 __iomem *intr_coal_delay_ptr;
 	int mtrr;
 	int wc_enabled;
-	int wake_queue;
-	int stop_queue;
 	int down_cnt;
 	wait_queue_head_t down_wq;
 	struct work_struct watchdog_work;
 	struct timer_list watchdog_timer;
-	int watchdog_tx_done;
-	int watchdog_tx_req;
-	int watchdog_pause;
 	int watchdog_resets;
-	int tx_linearized;
+	int watchdog_pause;
 	int pause;
 	char *fw_name;
 	char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE];
+	char *product_code_string;
 	char fw_version[128];
 	int fw_ver_major;
 	int fw_ver_minor;
@@ -228,58 +247,54 @@
 
 static char *myri10ge_fw_name = NULL;
 module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name\n");
+MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name");
 
 static int myri10ge_ecrc_enable = 1;
 module_param(myri10ge_ecrc_enable, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E\n");
-
-static int myri10ge_max_intr_slots = 1024;
-module_param(myri10ge_max_intr_slots, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_max_intr_slots, "Interrupt queue slots\n");
+MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E");
 
 static int myri10ge_small_bytes = -1;	/* -1 == auto */
 module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n");
+MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets");
 
 static int myri10ge_msi = 1;	/* enable msi by default */
 module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n");
+MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts");
 
 static int myri10ge_intr_coal_delay = 75;
 module_param(myri10ge_intr_coal_delay, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n");
+MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay");
 
 static int myri10ge_flow_control = 1;
 module_param(myri10ge_flow_control, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter\n");
+MODULE_PARM_DESC(myri10ge_flow_control, "Pause parameter");
 
 static int myri10ge_deassert_wait = 1;
 module_param(myri10ge_deassert_wait, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_deassert_wait,
-		 "Wait when deasserting legacy interrupts\n");
+		 "Wait when deasserting legacy interrupts");
 
 static int myri10ge_force_firmware = 0;
 module_param(myri10ge_force_firmware, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_force_firmware,
-		 "Force firmware to assume aligned completions\n");
+		 "Force firmware to assume aligned completions");
 
 static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
 module_param(myri10ge_initial_mtu, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n");
+MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU");
 
 static int myri10ge_napi_weight = 64;
 module_param(myri10ge_napi_weight, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight\n");
+MODULE_PARM_DESC(myri10ge_napi_weight, "Set NAPI weight");
 
 static int myri10ge_watchdog_timeout = 1;
 module_param(myri10ge_watchdog_timeout, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout\n");
+MODULE_PARM_DESC(myri10ge_watchdog_timeout, "Set watchdog timeout");
 
 static int myri10ge_max_irq_loops = 1048576;
 module_param(myri10ge_max_irq_loops, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_max_irq_loops,
-		 "Set stuck legacy IRQ detection threshold\n");
+		 "Set stuck legacy IRQ detection threshold");
 
 #define MYRI10GE_MSG_DEFAULT NETIF_MSG_LINK
 
@@ -289,21 +304,22 @@
 
 static int myri10ge_lro = 1;
 module_param(myri10ge_lro, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload\n");
+MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload");
 
 static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS;
 module_param(myri10ge_lro_max_pkts, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_lro, "Number of LRO packets to be aggregated\n");
+MODULE_PARM_DESC(myri10ge_lro_max_pkts,
+		 "Number of LRO packets to be aggregated");
 
 static int myri10ge_fill_thresh = 256;
 module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
+MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed");
 
 static int myri10ge_reset_recover = 1;
 
 static int myri10ge_wcfifo = 0;
 module_param(myri10ge_wcfifo, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
+MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled");
 
 #define MYRI10GE_FW_OFFSET 1024*1024
 #define MYRI10GE_HIGHPART_TO_U32(X) \
@@ -359,8 +375,10 @@
 		for (sleep_total = 0;
 		     sleep_total < 1000
 		     && response->result == htonl(MYRI10GE_NO_RESPONSE_RESULT);
-		     sleep_total += 10)
+		     sleep_total += 10) {
 			udelay(10);
+			mb();
+		}
 	} else {
 		/* use msleep for most command */
 		for (sleep_total = 0;
@@ -420,6 +438,10 @@
 				ptr += 1;
 			}
 		}
+		if (memcmp(ptr, "PC=", 3) == 0) {
+			ptr += 3;
+			mgp->product_code_string = ptr;
+		}
 		if (memcmp((const void *)ptr, "SN=", 3) == 0) {
 			ptr += 3;
 			mgp->serial_number = simple_strtoul(ptr, &ptr, 10);
@@ -442,7 +464,7 @@
 static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
 {
 	char __iomem *submit;
-	__be32 buf[16];
+	__be32 buf[16] __attribute__ ((__aligned__(8)));
 	u32 dma_low, dma_high;
 	int i;
 
@@ -609,13 +631,38 @@
 	return status;
 }
 
+int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp)
+{
+	struct myri10ge_cmd cmd;
+	int status;
+
+	/* probe for IPv6 TSO support */
+	mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+				   &cmd, 0);
+	if (status == 0) {
+		mgp->max_tso6 = cmd.data0;
+		mgp->features |= NETIF_F_TSO6;
+	}
+
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
+	if (status != 0) {
+		dev_err(&mgp->pdev->dev,
+			"failed MXGEFW_CMD_GET_RX_RING_SIZE\n");
+		return -ENXIO;
+	}
+
+	mgp->max_intr_slots = 2 * (cmd.data0 / sizeof(struct mcp_dma_addr));
+
+	return 0;
+}
+
 static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
 {
 	char __iomem *submit;
-	__be32 buf[16];
+	__be32 buf[16] __attribute__ ((__aligned__(8)));
 	u32 dma_low, dma_high, size;
 	int status, i;
-	struct myri10ge_cmd cmd;
 
 	size = 0;
 	status = myri10ge_load_hotplug_firmware(mgp, &size);
@@ -635,7 +682,7 @@
 		}
 		dev_info(&mgp->pdev->dev,
 			 "Successfully adopted running firmware\n");
-		if (mgp->tx.boundary == 4096) {
+		if (mgp->tx_boundary == 4096) {
 			dev_warn(&mgp->pdev->dev,
 				 "Using firmware currently running on NIC"
 				 ".  For optimal\n");
@@ -646,7 +693,9 @@
 		}
 
 		mgp->fw_name = "adopted";
-		mgp->tx.boundary = 2048;
+		mgp->tx_boundary = 2048;
+		myri10ge_dummy_rdma(mgp, 1);
+		status = myri10ge_get_firmware_capabilities(mgp);
 		return status;
 	}
 
@@ -681,26 +730,18 @@
 	msleep(1);
 	mb();
 	i = 0;
-	while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20) {
-		msleep(1);
+	while (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 9) {
+		msleep(1 << i);
 		i++;
 	}
 	if (mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA) {
 		dev_err(&mgp->pdev->dev, "handoff failed\n");
 		return -ENXIO;
 	}
-	dev_info(&mgp->pdev->dev, "handoff confirmed\n");
 	myri10ge_dummy_rdma(mgp, 1);
+	status = myri10ge_get_firmware_capabilities(mgp);
 
-	/* probe for IPv6 TSO support */
-	mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
-	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
-				   &cmd, 0);
-	if (status == 0) {
-		mgp->max_tso6 = cmd.data0;
-		mgp->features |= NETIF_F_TSO6;
-	}
-	return 0;
+	return status;
 }
 
 static int myri10ge_update_mac_address(struct myri10ge_priv *mgp, u8 * addr)
@@ -772,7 +813,7 @@
 	 * transfers took to complete.
 	 */
 
-	len = mgp->tx.boundary;
+	len = mgp->tx_boundary;
 
 	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
 	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
@@ -834,17 +875,17 @@
 
 	/* Now exchange information about interrupts  */
 
-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
-	memset(mgp->rx_done.entry, 0, bytes);
+	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
+	memset(mgp->ss.rx_done.entry, 0, bytes);
 	cmd.data0 = (u32) bytes;
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0);
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.rx_done.bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.rx_done.bus);
 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0);
 
 	status |=
 	    myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
-	mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
+	mgp->ss.irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
 				    &cmd, 0);
 	mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
@@ -858,17 +899,17 @@
 	}
 	put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
 
-	memset(mgp->rx_done.entry, 0, bytes);
+	memset(mgp->ss.rx_done.entry, 0, bytes);
 
 	/* reset mcp/driver shared state back to 0 */
-	mgp->tx.req = 0;
-	mgp->tx.done = 0;
-	mgp->tx.pkt_start = 0;
-	mgp->tx.pkt_done = 0;
-	mgp->rx_big.cnt = 0;
-	mgp->rx_small.cnt = 0;
-	mgp->rx_done.idx = 0;
-	mgp->rx_done.cnt = 0;
+	mgp->ss.tx.req = 0;
+	mgp->ss.tx.done = 0;
+	mgp->ss.tx.pkt_start = 0;
+	mgp->ss.tx.pkt_done = 0;
+	mgp->ss.rx_big.cnt = 0;
+	mgp->ss.rx_small.cnt = 0;
+	mgp->ss.rx_done.idx = 0;
+	mgp->ss.rx_done.cnt = 0;
 	mgp->link_changes = 0;
 	status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr);
 	myri10ge_change_pause(mgp, mgp->pause);
@@ -1020,9 +1061,10 @@
 				 * page into an skb */
 
 static inline int
-myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
+myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
 		 int bytes, int len, __wsum csum)
 {
+	struct myri10ge_priv *mgp = ss->mgp;
 	struct sk_buff *skb;
 	struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
 	int i, idx, hlen, remainder;
@@ -1052,11 +1094,10 @@
 		rx_frags[0].page_offset += MXGEFW_PAD;
 		rx_frags[0].size -= MXGEFW_PAD;
 		len -= MXGEFW_PAD;
-		lro_receive_frags(&mgp->rx_done.lro_mgr, rx_frags,
+		lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags,
 				  len, len,
-				 /* opaque, will come back in get_frag_header */
-				  (void *)(__force unsigned long)csum,
-				  csum);
+				  /* opaque, will come back in get_frag_header */
+				  (void *)(__force unsigned long)csum, csum);
 		return 1;
 	}
 
@@ -1096,10 +1137,11 @@
 	return 1;
 }
 
-static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
+static inline void
+myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
 {
-	struct pci_dev *pdev = mgp->pdev;
-	struct myri10ge_tx_buf *tx = &mgp->tx;
+	struct pci_dev *pdev = ss->mgp->pdev;
+	struct myri10ge_tx_buf *tx = &ss->tx;
 	struct sk_buff *skb;
 	int idx, len;
 
@@ -1117,8 +1159,8 @@
 		len = pci_unmap_len(&tx->info[idx], len);
 		pci_unmap_len_set(&tx->info[idx], len, 0);
 		if (skb) {
-			mgp->stats.tx_bytes += skb->len;
-			mgp->stats.tx_packets++;
+			ss->stats.tx_bytes += skb->len;
+			ss->stats.tx_packets++;
 			dev_kfree_skb_irq(skb);
 			if (len)
 				pci_unmap_single(pdev,
@@ -1134,16 +1176,18 @@
 		}
 	}
 	/* start the queue if we've stopped it */
-	if (netif_queue_stopped(mgp->dev)
+	if (netif_queue_stopped(ss->dev)
 	    && tx->req - tx->done < (tx->mask >> 1)) {
-		mgp->wake_queue++;
-		netif_wake_queue(mgp->dev);
+		tx->wake_queue++;
+		netif_wake_queue(ss->dev);
 	}
 }
 
-static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget)
+static inline int
+myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 {
-	struct myri10ge_rx_done *rx_done = &mgp->rx_done;
+	struct myri10ge_rx_done *rx_done = &ss->rx_done;
+	struct myri10ge_priv *mgp = ss->mgp;
 	unsigned long rx_bytes = 0;
 	unsigned long rx_packets = 0;
 	unsigned long rx_ok;
@@ -1159,40 +1203,40 @@
 		rx_done->entry[idx].length = 0;
 		checksum = csum_unfold(rx_done->entry[idx].checksum);
 		if (length <= mgp->small_bytes)
-			rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small,
+			rx_ok = myri10ge_rx_done(ss, &ss->rx_small,
 						 mgp->small_bytes,
 						 length, checksum);
 		else
-			rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big,
+			rx_ok = myri10ge_rx_done(ss, &ss->rx_big,
 						 mgp->big_bytes,
 						 length, checksum);
 		rx_packets += rx_ok;
 		rx_bytes += rx_ok * (unsigned long)length;
 		cnt++;
-		idx = cnt & (myri10ge_max_intr_slots - 1);
+		idx = cnt & (mgp->max_intr_slots - 1);
 		work_done++;
 	}
 	rx_done->idx = idx;
 	rx_done->cnt = cnt;
-	mgp->stats.rx_packets += rx_packets;
-	mgp->stats.rx_bytes += rx_bytes;
+	ss->stats.rx_packets += rx_packets;
+	ss->stats.rx_bytes += rx_bytes;
 
 	if (myri10ge_lro)
 		lro_flush_all(&rx_done->lro_mgr);
 
 	/* restock receive rings if needed */
-	if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh)
-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
+	if (ss->rx_small.fill_cnt - ss->rx_small.cnt < myri10ge_fill_thresh)
+		myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
 					mgp->small_bytes + MXGEFW_PAD, 0);
-	if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh)
-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
+	if (ss->rx_big.fill_cnt - ss->rx_big.cnt < myri10ge_fill_thresh)
+		myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0);
 
 	return work_done;
 }
 
 static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
 {
-	struct mcp_irq_data *stats = mgp->fw_stats;
+	struct mcp_irq_data *stats = mgp->ss.fw_stats;
 
 	if (unlikely(stats->stats_updated)) {
 		unsigned link_up = ntohl(stats->link_up);
@@ -1219,9 +1263,9 @@
 			}
 		}
 		if (mgp->rdma_tags_available !=
-		    ntohl(mgp->fw_stats->rdma_tags_available)) {
+		    ntohl(stats->rdma_tags_available)) {
 			mgp->rdma_tags_available =
-			    ntohl(mgp->fw_stats->rdma_tags_available);
+			    ntohl(stats->rdma_tags_available);
 			printk(KERN_WARNING "myri10ge: %s: RDMA timed out! "
 			       "%d tags left\n", mgp->dev->name,
 			       mgp->rdma_tags_available);
@@ -1234,26 +1278,27 @@
 
 static int myri10ge_poll(struct napi_struct *napi, int budget)
 {
-	struct myri10ge_priv *mgp =
-	    container_of(napi, struct myri10ge_priv, napi);
-	struct net_device *netdev = mgp->dev;
+	struct myri10ge_slice_state *ss =
+	    container_of(napi, struct myri10ge_slice_state, napi);
+	struct net_device *netdev = ss->mgp->dev;
 	int work_done;
 
 	/* process as many rx events as NAPI will allow */
-	work_done = myri10ge_clean_rx_done(mgp, budget);
+	work_done = myri10ge_clean_rx_done(ss, budget);
 
 	if (work_done < budget) {
 		netif_rx_complete(netdev, napi);
-		put_be32(htonl(3), mgp->irq_claim);
+		put_be32(htonl(3), ss->irq_claim);
 	}
 	return work_done;
 }
 
 static irqreturn_t myri10ge_intr(int irq, void *arg)
 {
-	struct myri10ge_priv *mgp = arg;
-	struct mcp_irq_data *stats = mgp->fw_stats;
-	struct myri10ge_tx_buf *tx = &mgp->tx;
+	struct myri10ge_slice_state *ss = arg;
+	struct myri10ge_priv *mgp = ss->mgp;
+	struct mcp_irq_data *stats = ss->fw_stats;
+	struct myri10ge_tx_buf *tx = &ss->tx;
 	u32 send_done_count;
 	int i;
 
@@ -1264,7 +1309,7 @@
 	/* low bit indicates receives are present, so schedule
 	 * napi poll handler */
 	if (stats->valid & 1)
-		netif_rx_schedule(mgp->dev, &mgp->napi);
+		netif_rx_schedule(ss->dev, &ss->napi);
 
 	if (!mgp->msi_enabled) {
 		put_be32(0, mgp->irq_deassert);
@@ -1281,7 +1326,7 @@
 		/* check for transmit completes and receives */
 		send_done_count = ntohl(stats->send_done_count);
 		if (send_done_count != tx->pkt_done)
-			myri10ge_tx_done(mgp, (int)send_done_count);
+			myri10ge_tx_done(ss, (int)send_done_count);
 		if (unlikely(i > myri10ge_max_irq_loops)) {
 			printk(KERN_WARNING "myri10ge: %s: irq stuck?\n",
 			       mgp->dev->name);
@@ -1296,16 +1341,46 @@
 
 	myri10ge_check_statblock(mgp);
 
-	put_be32(htonl(3), mgp->irq_claim + 1);
+	put_be32(htonl(3), ss->irq_claim + 1);
 	return (IRQ_HANDLED);
 }
 
 static int
 myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 {
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	char *ptr;
+	int i;
+
 	cmd->autoneg = AUTONEG_DISABLE;
 	cmd->speed = SPEED_10000;
 	cmd->duplex = DUPLEX_FULL;
+
+	/*
+	 * parse the product code to deterimine the interface type
+	 * (CX4, XFP, Quad Ribbon Fiber) by looking at the character
+	 * after the 3rd dash in the driver's cached copy of the
+	 * EEPROM's product code string.
+	 */
+	ptr = mgp->product_code_string;
+	if (ptr == NULL) {
+		printk(KERN_ERR "myri10ge: %s: Missing product code\n",
+		       netdev->name);
+		return 0;
+	}
+	for (i = 0; i < 3; i++, ptr++) {
+		ptr = strchr(ptr, '-');
+		if (ptr == NULL) {
+			printk(KERN_ERR "myri10ge: %s: Invalid product "
+			       "code %s\n", netdev->name,
+			       mgp->product_code_string);
+			return 0;
+		}
+	}
+	if (*ptr == 'R' || *ptr == 'Q') {
+		/* We've found either an XFP or quad ribbon fiber */
+		cmd->port = PORT_FIBRE;
+	}
 	return 0;
 }
 
@@ -1324,6 +1399,7 @@
 myri10ge_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal)
 {
 	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
 	coal->rx_coalesce_usecs = mgp->intr_coal_delay;
 	return 0;
 }
@@ -1370,10 +1446,10 @@
 {
 	struct myri10ge_priv *mgp = netdev_priv(netdev);
 
-	ring->rx_mini_max_pending = mgp->rx_small.mask + 1;
-	ring->rx_max_pending = mgp->rx_big.mask + 1;
+	ring->rx_mini_max_pending = mgp->ss.rx_small.mask + 1;
+	ring->rx_max_pending = mgp->ss.rx_big.mask + 1;
 	ring->rx_jumbo_max_pending = 0;
-	ring->tx_max_pending = mgp->rx_small.mask + 1;
+	ring->tx_max_pending = mgp->ss.rx_small.mask + 1;
 	ring->rx_mini_pending = ring->rx_mini_max_pending;
 	ring->rx_pending = ring->rx_max_pending;
 	ring->rx_jumbo_pending = ring->rx_jumbo_max_pending;
@@ -1383,6 +1459,7 @@
 static u32 myri10ge_get_rx_csum(struct net_device *netdev)
 {
 	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
 	if (mgp->csum_flag)
 		return 1;
 	else
@@ -1392,6 +1469,7 @@
 static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
 {
 	struct myri10ge_priv *mgp = netdev_priv(netdev);
+
 	if (csum_enabled)
 		mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
 	else
@@ -1411,7 +1489,7 @@
 	return 0;
 }
 
-static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
+static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
 	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
 	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
 	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
@@ -1421,28 +1499,39 @@
 	/* device-specific stats */
 	"tx_boundary", "WC", "irq", "MSI",
 	"read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
-	"serial_number", "tx_pkt_start", "tx_pkt_done",
-	"tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt",
-	"wake_queue", "stop_queue", "watchdog_resets", "tx_linearized",
+	"serial_number", "watchdog_resets",
 	"link_changes", "link_up", "dropped_link_overflow",
 	"dropped_link_error_or_filtered",
 	"dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
 	"dropped_unicast_filtered", "dropped_multicast_filtered",
 	"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
-	"dropped_no_big_buffer", "LRO aggregated", "LRO flushed",
+	"dropped_no_big_buffer"
+};
+
+static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = {
+	"----------- slice ---------",
+	"tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done",
+	"rx_small_cnt", "rx_big_cnt",
+	"wake_queue", "stop_queue", "tx_linearized", "LRO aggregated",
+	    "LRO flushed",
 	"LRO avg aggr", "LRO no_desc"
 };
 
 #define MYRI10GE_NET_STATS_LEN      21
-#define MYRI10GE_STATS_LEN	ARRAY_SIZE(myri10ge_gstrings_stats)
+#define MYRI10GE_MAIN_STATS_LEN  ARRAY_SIZE(myri10ge_gstrings_main_stats)
+#define MYRI10GE_SLICE_STATS_LEN  ARRAY_SIZE(myri10ge_gstrings_slice_stats)
 
 static void
 myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
 {
 	switch (stringset) {
 	case ETH_SS_STATS:
-		memcpy(data, *myri10ge_gstrings_stats,
-		       sizeof(myri10ge_gstrings_stats));
+		memcpy(data, *myri10ge_gstrings_main_stats,
+		       sizeof(myri10ge_gstrings_main_stats));
+		data += sizeof(myri10ge_gstrings_main_stats);
+		memcpy(data, *myri10ge_gstrings_slice_stats,
+		       sizeof(myri10ge_gstrings_slice_stats));
+		data += sizeof(myri10ge_gstrings_slice_stats);
 		break;
 	}
 }
@@ -1451,7 +1540,7 @@
 {
 	switch (sset) {
 	case ETH_SS_STATS:
-		return MYRI10GE_STATS_LEN;
+		return MYRI10GE_MAIN_STATS_LEN + MYRI10GE_SLICE_STATS_LEN;
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -1462,12 +1551,13 @@
 			   struct ethtool_stats *stats, u64 * data)
 {
 	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	struct myri10ge_slice_state *ss;
 	int i;
 
 	for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
 		data[i] = ((unsigned long *)&mgp->stats)[i];
 
-	data[i++] = (unsigned int)mgp->tx.boundary;
+	data[i++] = (unsigned int)mgp->tx_boundary;
 	data[i++] = (unsigned int)mgp->wc_enabled;
 	data[i++] = (unsigned int)mgp->pdev->irq;
 	data[i++] = (unsigned int)mgp->msi_enabled;
@@ -1475,40 +1565,44 @@
 	data[i++] = (unsigned int)mgp->write_dma;
 	data[i++] = (unsigned int)mgp->read_write_dma;
 	data[i++] = (unsigned int)mgp->serial_number;
-	data[i++] = (unsigned int)mgp->tx.pkt_start;
-	data[i++] = (unsigned int)mgp->tx.pkt_done;
-	data[i++] = (unsigned int)mgp->tx.req;
-	data[i++] = (unsigned int)mgp->tx.done;
-	data[i++] = (unsigned int)mgp->rx_small.cnt;
-	data[i++] = (unsigned int)mgp->rx_big.cnt;
-	data[i++] = (unsigned int)mgp->wake_queue;
-	data[i++] = (unsigned int)mgp->stop_queue;
 	data[i++] = (unsigned int)mgp->watchdog_resets;
-	data[i++] = (unsigned int)mgp->tx_linearized;
 	data[i++] = (unsigned int)mgp->link_changes;
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow);
+
+	/* firmware stats are useful only in the first slice */
+	ss = &mgp->ss;
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->link_up);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_link_overflow);
 	data[i++] =
-	    (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32);
+	    (unsigned int)ntohl(ss->fw_stats->dropped_link_error_or_filtered);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_pause);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_phy);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_bad_crc32);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_unicast_filtered);
 	data[i++] =
-	    (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered);
-	data[i++] =
-	    (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer);
-	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer);
-	data[i++] = mgp->rx_done.lro_mgr.stats.aggregated;
-	data[i++] = mgp->rx_done.lro_mgr.stats.flushed;
-	if (mgp->rx_done.lro_mgr.stats.flushed)
-		data[i++] = mgp->rx_done.lro_mgr.stats.aggregated /
-		    mgp->rx_done.lro_mgr.stats.flushed;
+	    (unsigned int)ntohl(ss->fw_stats->dropped_multicast_filtered);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_runt);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_overrun);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_small_buffer);
+	data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_big_buffer);
+
+	data[i++] = 0;
+	data[i++] = (unsigned int)ss->tx.pkt_start;
+	data[i++] = (unsigned int)ss->tx.pkt_done;
+	data[i++] = (unsigned int)ss->tx.req;
+	data[i++] = (unsigned int)ss->tx.done;
+	data[i++] = (unsigned int)ss->rx_small.cnt;
+	data[i++] = (unsigned int)ss->rx_big.cnt;
+	data[i++] = (unsigned int)ss->tx.wake_queue;
+	data[i++] = (unsigned int)ss->tx.stop_queue;
+	data[i++] = (unsigned int)ss->tx.linearized;
+	data[i++] = ss->rx_done.lro_mgr.stats.aggregated;
+	data[i++] = ss->rx_done.lro_mgr.stats.flushed;
+	if (ss->rx_done.lro_mgr.stats.flushed)
+		data[i++] = ss->rx_done.lro_mgr.stats.aggregated /
+		    ss->rx_done.lro_mgr.stats.flushed;
 	else
 		data[i++] = 0;
-	data[i++] = mgp->rx_done.lro_mgr.stats.no_desc;
+	data[i++] = ss->rx_done.lro_mgr.stats.no_desc;
 }
 
 static void myri10ge_set_msglevel(struct net_device *netdev, u32 value)
@@ -1544,19 +1638,17 @@
 	.get_msglevel = myri10ge_get_msglevel
 };
 
-static int myri10ge_allocate_rings(struct net_device *dev)
+static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
 {
-	struct myri10ge_priv *mgp;
+	struct myri10ge_priv *mgp = ss->mgp;
 	struct myri10ge_cmd cmd;
+	struct net_device *dev = mgp->dev;
 	int tx_ring_size, rx_ring_size;
 	int tx_ring_entries, rx_ring_entries;
 	int i, status;
 	size_t bytes;
 
-	mgp = netdev_priv(dev);
-
 	/* get ring sizes */
-
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
 	tx_ring_size = cmd.data0;
 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
@@ -1566,144 +1658,142 @@
 
 	tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send);
 	rx_ring_entries = rx_ring_size / sizeof(struct mcp_dma_addr);
-	mgp->tx.mask = tx_ring_entries - 1;
-	mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1;
+	ss->tx.mask = tx_ring_entries - 1;
+	ss->rx_small.mask = ss->rx_big.mask = rx_ring_entries - 1;
 
 	status = -ENOMEM;
 
 	/* allocate the host shadow rings */
 
 	bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4)
-	    * sizeof(*mgp->tx.req_list);
-	mgp->tx.req_bytes = kzalloc(bytes, GFP_KERNEL);
-	if (mgp->tx.req_bytes == NULL)
+	    * sizeof(*ss->tx.req_list);
+	ss->tx.req_bytes = kzalloc(bytes, GFP_KERNEL);
+	if (ss->tx.req_bytes == NULL)
 		goto abort_with_nothing;
 
 	/* ensure req_list entries are aligned to 8 bytes */
-	mgp->tx.req_list = (struct mcp_kreq_ether_send *)
-	    ALIGN((unsigned long)mgp->tx.req_bytes, 8);
+	ss->tx.req_list = (struct mcp_kreq_ether_send *)
+	    ALIGN((unsigned long)ss->tx.req_bytes, 8);
 
-	bytes = rx_ring_entries * sizeof(*mgp->rx_small.shadow);
-	mgp->rx_small.shadow = kzalloc(bytes, GFP_KERNEL);
-	if (mgp->rx_small.shadow == NULL)
+	bytes = rx_ring_entries * sizeof(*ss->rx_small.shadow);
+	ss->rx_small.shadow = kzalloc(bytes, GFP_KERNEL);
+	if (ss->rx_small.shadow == NULL)
 		goto abort_with_tx_req_bytes;
 
-	bytes = rx_ring_entries * sizeof(*mgp->rx_big.shadow);
-	mgp->rx_big.shadow = kzalloc(bytes, GFP_KERNEL);
-	if (mgp->rx_big.shadow == NULL)
+	bytes = rx_ring_entries * sizeof(*ss->rx_big.shadow);
+	ss->rx_big.shadow = kzalloc(bytes, GFP_KERNEL);
+	if (ss->rx_big.shadow == NULL)
 		goto abort_with_rx_small_shadow;
 
 	/* allocate the host info rings */
 
-	bytes = tx_ring_entries * sizeof(*mgp->tx.info);
-	mgp->tx.info = kzalloc(bytes, GFP_KERNEL);
-	if (mgp->tx.info == NULL)
+	bytes = tx_ring_entries * sizeof(*ss->tx.info);
+	ss->tx.info = kzalloc(bytes, GFP_KERNEL);
+	if (ss->tx.info == NULL)
 		goto abort_with_rx_big_shadow;
 
-	bytes = rx_ring_entries * sizeof(*mgp->rx_small.info);
-	mgp->rx_small.info = kzalloc(bytes, GFP_KERNEL);
-	if (mgp->rx_small.info == NULL)
+	bytes = rx_ring_entries * sizeof(*ss->rx_small.info);
+	ss->rx_small.info = kzalloc(bytes, GFP_KERNEL);
+	if (ss->rx_small.info == NULL)
 		goto abort_with_tx_info;
 
-	bytes = rx_ring_entries * sizeof(*mgp->rx_big.info);
-	mgp->rx_big.info = kzalloc(bytes, GFP_KERNEL);
-	if (mgp->rx_big.info == NULL)
+	bytes = rx_ring_entries * sizeof(*ss->rx_big.info);
+	ss->rx_big.info = kzalloc(bytes, GFP_KERNEL);
+	if (ss->rx_big.info == NULL)
 		goto abort_with_rx_small_info;
 
 	/* Fill the receive rings */
-	mgp->rx_big.cnt = 0;
-	mgp->rx_small.cnt = 0;
-	mgp->rx_big.fill_cnt = 0;
-	mgp->rx_small.fill_cnt = 0;
-	mgp->rx_small.page_offset = MYRI10GE_ALLOC_SIZE;
-	mgp->rx_big.page_offset = MYRI10GE_ALLOC_SIZE;
-	mgp->rx_small.watchdog_needed = 0;
-	mgp->rx_big.watchdog_needed = 0;
-	myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
+	ss->rx_big.cnt = 0;
+	ss->rx_small.cnt = 0;
+	ss->rx_big.fill_cnt = 0;
+	ss->rx_small.fill_cnt = 0;
+	ss->rx_small.page_offset = MYRI10GE_ALLOC_SIZE;
+	ss->rx_big.page_offset = MYRI10GE_ALLOC_SIZE;
+	ss->rx_small.watchdog_needed = 0;
+	ss->rx_big.watchdog_needed = 0;
+	myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
 				mgp->small_bytes + MXGEFW_PAD, 0);
 
-	if (mgp->rx_small.fill_cnt < mgp->rx_small.mask + 1) {
+	if (ss->rx_small.fill_cnt < ss->rx_small.mask + 1) {
 		printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n",
-		       dev->name, mgp->rx_small.fill_cnt);
+		       dev->name, ss->rx_small.fill_cnt);
 		goto abort_with_rx_small_ring;
 	}
 
-	myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
-	if (mgp->rx_big.fill_cnt < mgp->rx_big.mask + 1) {
+	myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0);
+	if (ss->rx_big.fill_cnt < ss->rx_big.mask + 1) {
 		printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n",
-		       dev->name, mgp->rx_big.fill_cnt);
+		       dev->name, ss->rx_big.fill_cnt);
 		goto abort_with_rx_big_ring;
 	}
 
 	return 0;
 
 abort_with_rx_big_ring:
-	for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
-		int idx = i & mgp->rx_big.mask;
-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
+	for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) {
+		int idx = i & ss->rx_big.mask;
+		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx],
 				       mgp->big_bytes);
-		put_page(mgp->rx_big.info[idx].page);
+		put_page(ss->rx_big.info[idx].page);
 	}
 
 abort_with_rx_small_ring:
-	for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
-		int idx = i & mgp->rx_small.mask;
-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
+	for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) {
+		int idx = i & ss->rx_small.mask;
+		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx],
 				       mgp->small_bytes + MXGEFW_PAD);
-		put_page(mgp->rx_small.info[idx].page);
+		put_page(ss->rx_small.info[idx].page);
 	}
 
-	kfree(mgp->rx_big.info);
+	kfree(ss->rx_big.info);
 
 abort_with_rx_small_info:
-	kfree(mgp->rx_small.info);
+	kfree(ss->rx_small.info);
 
 abort_with_tx_info:
-	kfree(mgp->tx.info);
+	kfree(ss->tx.info);
 
 abort_with_rx_big_shadow:
-	kfree(mgp->rx_big.shadow);
+	kfree(ss->rx_big.shadow);
 
 abort_with_rx_small_shadow:
-	kfree(mgp->rx_small.shadow);
+	kfree(ss->rx_small.shadow);
 
 abort_with_tx_req_bytes:
-	kfree(mgp->tx.req_bytes);
-	mgp->tx.req_bytes = NULL;
-	mgp->tx.req_list = NULL;
+	kfree(ss->tx.req_bytes);
+	ss->tx.req_bytes = NULL;
+	ss->tx.req_list = NULL;
 
 abort_with_nothing:
 	return status;
 }
 
-static void myri10ge_free_rings(struct net_device *dev)
+static void myri10ge_free_rings(struct myri10ge_slice_state *ss)
 {
-	struct myri10ge_priv *mgp;
+	struct myri10ge_priv *mgp = ss->mgp;
 	struct sk_buff *skb;
 	struct myri10ge_tx_buf *tx;
 	int i, len, idx;
 
-	mgp = netdev_priv(dev);
-
-	for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
-		idx = i & mgp->rx_big.mask;
-		if (i == mgp->rx_big.fill_cnt - 1)
-			mgp->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE;
-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
+	for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) {
+		idx = i & ss->rx_big.mask;
+		if (i == ss->rx_big.fill_cnt - 1)
+			ss->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE;
+		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_big.info[idx],
 				       mgp->big_bytes);
-		put_page(mgp->rx_big.info[idx].page);
+		put_page(ss->rx_big.info[idx].page);
 	}
 
-	for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
-		idx = i & mgp->rx_small.mask;
-		if (i == mgp->rx_small.fill_cnt - 1)
-			mgp->rx_small.info[idx].page_offset =
+	for (i = ss->rx_small.cnt; i < ss->rx_small.fill_cnt; i++) {
+		idx = i & ss->rx_small.mask;
+		if (i == ss->rx_small.fill_cnt - 1)
+			ss->rx_small.info[idx].page_offset =
 			    MYRI10GE_ALLOC_SIZE;
-		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
+		myri10ge_unmap_rx_page(mgp->pdev, &ss->rx_small.info[idx],
 				       mgp->small_bytes + MXGEFW_PAD);
-		put_page(mgp->rx_small.info[idx].page);
+		put_page(ss->rx_small.info[idx].page);
 	}
-	tx = &mgp->tx;
+	tx = &ss->tx;
 	while (tx->done != tx->req) {
 		idx = tx->done & tx->mask;
 		skb = tx->info[idx].skb;
@@ -1714,7 +1804,7 @@
 		len = pci_unmap_len(&tx->info[idx], len);
 		pci_unmap_len_set(&tx->info[idx], len, 0);
 		if (skb) {
-			mgp->stats.tx_dropped++;
+			ss->stats.tx_dropped++;
 			dev_kfree_skb_any(skb);
 			if (len)
 				pci_unmap_single(mgp->pdev,
@@ -1729,19 +1819,19 @@
 					       PCI_DMA_TODEVICE);
 		}
 	}
-	kfree(mgp->rx_big.info);
+	kfree(ss->rx_big.info);
 
-	kfree(mgp->rx_small.info);
+	kfree(ss->rx_small.info);
 
-	kfree(mgp->tx.info);
+	kfree(ss->tx.info);
 
-	kfree(mgp->rx_big.shadow);
+	kfree(ss->rx_big.shadow);
 
-	kfree(mgp->rx_small.shadow);
+	kfree(ss->rx_small.shadow);
 
-	kfree(mgp->tx.req_bytes);
-	mgp->tx.req_bytes = NULL;
-	mgp->tx.req_list = NULL;
+	kfree(ss->tx.req_bytes);
+	ss->tx.req_bytes = NULL;
+	ss->tx.req_list = NULL;
 }
 
 static int myri10ge_request_irq(struct myri10ge_priv *mgp)
@@ -1840,13 +1930,11 @@
 
 static int myri10ge_open(struct net_device *dev)
 {
-	struct myri10ge_priv *mgp;
+	struct myri10ge_priv *mgp = netdev_priv(dev);
 	struct myri10ge_cmd cmd;
 	struct net_lro_mgr *lro_mgr;
 	int status, big_pow2;
 
-	mgp = netdev_priv(dev);
-
 	if (mgp->running != MYRI10GE_ETH_STOPPED)
 		return -EBUSY;
 
@@ -1883,16 +1971,16 @@
 	/* get the lanai pointers to the send and receive rings */
 
 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
-	mgp->tx.lanai =
+	mgp->ss.tx.lanai =
 	    (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0);
 
 	status |=
 	    myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0);
-	mgp->rx_small.lanai =
+	mgp->ss.rx_small.lanai =
 	    (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
 
 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0);
-	mgp->rx_big.lanai =
+	mgp->ss.rx_big.lanai =
 	    (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
 
 	if (status != 0) {
@@ -1904,15 +1992,15 @@
 	}
 
 	if (myri10ge_wcfifo && mgp->wc_enabled) {
-		mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
-		mgp->rx_small.wc_fifo =
+		mgp->ss.tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
+		mgp->ss.rx_small.wc_fifo =
 		    (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
-		mgp->rx_big.wc_fifo =
+		mgp->ss.rx_big.wc_fifo =
 		    (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG;
 	} else {
-		mgp->tx.wc_fifo = NULL;
-		mgp->rx_small.wc_fifo = NULL;
-		mgp->rx_big.wc_fifo = NULL;
+		mgp->ss.tx.wc_fifo = NULL;
+		mgp->ss.rx_small.wc_fifo = NULL;
+		mgp->ss.rx_big.wc_fifo = NULL;
 	}
 
 	/* Firmware needs the big buff size as a power of 2.  Lie and
@@ -1929,7 +2017,7 @@
 		mgp->big_bytes = big_pow2;
 	}
 
-	status = myri10ge_allocate_rings(dev);
+	status = myri10ge_allocate_rings(&mgp->ss);
 	if (status != 0)
 		goto abort_with_irq;
 
@@ -1948,12 +2036,12 @@
 		goto abort_with_rings;
 	}
 
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.fw_stats_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.fw_stats_bus);
 	cmd.data2 = sizeof(struct mcp_irq_data);
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0);
 	if (status == -ENOSYS) {
-		dma_addr_t bus = mgp->fw_stats_bus;
+		dma_addr_t bus = mgp->ss.fw_stats_bus;
 		bus += offsetof(struct mcp_irq_data, send_done_count);
 		cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus);
 		cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus);
@@ -1974,20 +2062,20 @@
 	mgp->link_state = ~0U;
 	mgp->rdma_tags_available = 15;
 
-	lro_mgr = &mgp->rx_done.lro_mgr;
+	lro_mgr = &mgp->ss.rx_done.lro_mgr;
 	lro_mgr->dev = dev;
 	lro_mgr->features = LRO_F_NAPI;
 	lro_mgr->ip_summed = CHECKSUM_COMPLETE;
 	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
 	lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS;
-	lro_mgr->lro_arr = mgp->rx_done.lro_desc;
+	lro_mgr->lro_arr = mgp->ss.rx_done.lro_desc;
 	lro_mgr->get_frag_header = myri10ge_get_frag_header;
 	lro_mgr->max_aggr = myri10ge_lro_max_pkts;
 	lro_mgr->frag_align_pad = 2;
 	if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
 		lro_mgr->max_aggr = MAX_SKB_FRAGS;
 
-	napi_enable(&mgp->napi);	/* must happen prior to any irq */
+	napi_enable(&mgp->ss.napi);	/* must happen prior to any irq */
 
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0);
 	if (status) {
@@ -1996,8 +2084,8 @@
 		goto abort_with_rings;
 	}
 
-	mgp->wake_queue = 0;
-	mgp->stop_queue = 0;
+	mgp->ss.tx.wake_queue = 0;
+	mgp->ss.tx.stop_queue = 0;
 	mgp->running = MYRI10GE_ETH_RUNNING;
 	mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ;
 	add_timer(&mgp->watchdog_timer);
@@ -2005,7 +2093,7 @@
 	return 0;
 
 abort_with_rings:
-	myri10ge_free_rings(dev);
+	myri10ge_free_rings(&mgp->ss);
 
 abort_with_irq:
 	myri10ge_free_irq(mgp);
@@ -2017,21 +2105,19 @@
 
 static int myri10ge_close(struct net_device *dev)
 {
-	struct myri10ge_priv *mgp;
+	struct myri10ge_priv *mgp = netdev_priv(dev);
 	struct myri10ge_cmd cmd;
 	int status, old_down_cnt;
 
-	mgp = netdev_priv(dev);
-
 	if (mgp->running != MYRI10GE_ETH_RUNNING)
 		return 0;
 
-	if (mgp->tx.req_bytes == NULL)
+	if (mgp->ss.tx.req_bytes == NULL)
 		return 0;
 
 	del_timer_sync(&mgp->watchdog_timer);
 	mgp->running = MYRI10GE_ETH_STOPPING;
-	napi_disable(&mgp->napi);
+	napi_disable(&mgp->ss.napi);
 	netif_carrier_off(dev);
 	netif_stop_queue(dev);
 	old_down_cnt = mgp->down_cnt;
@@ -2047,7 +2133,7 @@
 
 	netif_tx_disable(dev);
 	myri10ge_free_irq(mgp);
-	myri10ge_free_rings(dev);
+	myri10ge_free_rings(&mgp->ss);
 
 	mgp->running = MYRI10GE_ETH_STOPPED;
 	return 0;
@@ -2143,7 +2229,7 @@
 
 /*
  * Transmit a packet.  We need to split the packet so that a single
- * segment does not cross myri10ge->tx.boundary, so this makes segment
+ * segment does not cross myri10ge->tx_boundary, so this makes segment
  * counting tricky.  So rather than try to count segments up front, we
  * just give up if there are too few segments to hold a reasonably
  * fragmented packet currently available.  If we run
@@ -2154,8 +2240,9 @@
 static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct myri10ge_priv *mgp = netdev_priv(dev);
+	struct myri10ge_slice_state *ss;
 	struct mcp_kreq_ether_send *req;
-	struct myri10ge_tx_buf *tx = &mgp->tx;
+	struct myri10ge_tx_buf *tx;
 	struct skb_frag_struct *frag;
 	dma_addr_t bus;
 	u32 low;
@@ -2166,6 +2253,9 @@
 	int cum_len, seglen, boundary, rdma_count;
 	u8 flags, odd_flag;
 
+	/* always transmit through slot 0 */
+	ss = &mgp->ss;
+	tx = &ss->tx;
 again:
 	req = tx->req_list;
 	avail = tx->mask - 1 - (tx->req - tx->done);
@@ -2180,7 +2270,7 @@
 
 	if ((unlikely(avail < max_segments))) {
 		/* we are out of transmit resources */
-		mgp->stop_queue++;
+		tx->stop_queue++;
 		netif_stop_queue(dev);
 		return 1;
 	}
@@ -2242,7 +2332,7 @@
 			if (skb_padto(skb, ETH_ZLEN)) {
 				/* The packet is gone, so we must
 				 * return 0 */
-				mgp->stats.tx_dropped += 1;
+				ss->stats.tx_dropped += 1;
 				return 0;
 			}
 			/* adjust the len to account for the zero pad
@@ -2284,7 +2374,7 @@
 
 	while (1) {
 		/* Break the SKB or Fragment up into pieces which
-		 * do not cross mgp->tx.boundary */
+		 * do not cross mgp->tx_boundary */
 		low = MYRI10GE_LOWPART_TO_U32(bus);
 		high_swapped = htonl(MYRI10GE_HIGHPART_TO_U32(bus));
 		while (len) {
@@ -2294,7 +2384,8 @@
 			if (unlikely(count == max_segments))
 				goto abort_linearize;
 
-			boundary = (low + tx->boundary) & ~(tx->boundary - 1);
+			boundary =
+			    (low + mgp->tx_boundary) & ~(mgp->tx_boundary - 1);
 			seglen = boundary - low;
 			if (seglen > len)
 				seglen = len;
@@ -2378,7 +2469,7 @@
 		myri10ge_submit_req_wc(tx, tx->req_list, count);
 	tx->pkt_start++;
 	if ((avail - count) < MXGEFW_MAX_SEND_DESC) {
-		mgp->stop_queue++;
+		tx->stop_queue++;
 		netif_stop_queue(dev);
 	}
 	dev->trans_start = jiffies;
@@ -2420,12 +2511,12 @@
 	if (skb_linearize(skb))
 		goto drop;
 
-	mgp->tx_linearized++;
+	tx->linearized++;
 	goto again;
 
 drop:
 	dev_kfree_skb_any(skb);
-	mgp->stats.tx_dropped += 1;
+	ss->stats.tx_dropped += 1;
 	return 0;
 
 }
@@ -2433,7 +2524,7 @@
 static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
 {
 	struct sk_buff *segs, *curr;
-	struct myri10ge_priv *mgp = dev->priv;
+	struct myri10ge_priv *mgp = netdev_priv(dev);
 	int status;
 
 	segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6);
@@ -2473,14 +2564,13 @@
 
 static void myri10ge_set_multicast_list(struct net_device *dev)
 {
+	struct myri10ge_priv *mgp = netdev_priv(dev);
 	struct myri10ge_cmd cmd;
-	struct myri10ge_priv *mgp;
 	struct dev_mc_list *mc_list;
 	__be32 data[2] = { 0, 0 };
 	int err;
 	DECLARE_MAC_BUF(mac);
 
-	mgp = netdev_priv(dev);
 	/* can be called from atomic contexts,
 	 * pass 1 to force atomicity in myri10ge_send_cmd() */
 	myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1);
@@ -2616,13 +2706,14 @@
 	ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4;
 	if (ext_type != PCI_EXP_TYPE_ROOT_PORT) {
 		if (myri10ge_ecrc_enable > 1) {
-			struct pci_dev *old_bridge = bridge;
+			struct pci_dev *prev_bridge, *old_bridge = bridge;
 
 			/* Walk the hierarchy up to the root port
 			 * where ECRC has to be enabled */
 			do {
+				prev_bridge = bridge;
 				bridge = bridge->bus->self;
-				if (!bridge) {
+				if (!bridge || prev_bridge == bridge) {
 					dev_err(dev,
 						"Failed to find root port"
 						" to force ECRC\n");
@@ -2681,9 +2772,9 @@
  * already been enabled, then it must use a firmware image which works
  * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it
  * should also ensure that it never gives the device a Read-DMA which is
- * larger than 2KB by setting the tx.boundary to 2KB.  If ECRC is
+ * larger than 2KB by setting the tx_boundary to 2KB.  If ECRC is
  * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat)
- * firmware image, and set tx.boundary to 4KB.
+ * firmware image, and set tx_boundary to 4KB.
  */
 
 static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
@@ -2692,7 +2783,7 @@
 	struct device *dev = &pdev->dev;
 	int status;
 
-	mgp->tx.boundary = 4096;
+	mgp->tx_boundary = 4096;
 	/*
 	 * Verify the max read request size was set to 4KB
 	 * before trying the test with 4KB.
@@ -2704,7 +2795,7 @@
 	}
 	if (status != 4096) {
 		dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status);
-		mgp->tx.boundary = 2048;
+		mgp->tx_boundary = 2048;
 	}
 	/*
 	 * load the optimized firmware (which assumes aligned PCIe
@@ -2737,7 +2828,7 @@
 			 "Please install up to date fw\n");
 abort:
 	/* fall back to using the unaligned firmware */
-	mgp->tx.boundary = 2048;
+	mgp->tx_boundary = 2048;
 	mgp->fw_name = myri10ge_fw_unaligned;
 
 }
@@ -2758,7 +2849,7 @@
 		if (link_width < 8) {
 			dev_info(&mgp->pdev->dev, "PCIE x%d Link\n",
 				 link_width);
-			mgp->tx.boundary = 4096;
+			mgp->tx_boundary = 4096;
 			mgp->fw_name = myri10ge_fw_aligned;
 		} else {
 			myri10ge_firmware_probe(mgp);
@@ -2767,12 +2858,12 @@
 		if (myri10ge_force_firmware == 1) {
 			dev_info(&mgp->pdev->dev,
 				 "Assuming aligned completions (forced)\n");
-			mgp->tx.boundary = 4096;
+			mgp->tx_boundary = 4096;
 			mgp->fw_name = myri10ge_fw_aligned;
 		} else {
 			dev_info(&mgp->pdev->dev,
 				 "Assuming unaligned completions (forced)\n");
-			mgp->tx.boundary = 2048;
+			mgp->tx_boundary = 2048;
 			mgp->fw_name = myri10ge_fw_unaligned;
 		}
 	}
@@ -2889,6 +2980,7 @@
 {
 	struct myri10ge_priv *mgp =
 	    container_of(work, struct myri10ge_priv, watchdog_work);
+	struct myri10ge_tx_buf *tx;
 	u32 reboot;
 	int status;
 	u16 cmd, vendor;
@@ -2938,15 +3030,16 @@
 
 		printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n",
 		       mgp->dev->name);
+		tx = &mgp->ss.tx;
 		printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
-		       mgp->dev->name, mgp->tx.req, mgp->tx.done,
-		       mgp->tx.pkt_start, mgp->tx.pkt_done,
-		       (int)ntohl(mgp->fw_stats->send_done_count));
+		       mgp->dev->name, tx->req, tx->done,
+		       tx->pkt_start, tx->pkt_done,
+		       (int)ntohl(mgp->ss.fw_stats->send_done_count));
 		msleep(2000);
 		printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
-		       mgp->dev->name, mgp->tx.req, mgp->tx.done,
-		       mgp->tx.pkt_start, mgp->tx.pkt_done,
-		       (int)ntohl(mgp->fw_stats->send_done_count));
+		       mgp->dev->name, tx->req, tx->done,
+		       tx->pkt_start, tx->pkt_done,
+		       (int)ntohl(mgp->ss.fw_stats->send_done_count));
 	}
 	rtnl_lock();
 	myri10ge_close(mgp->dev);
@@ -2969,28 +3062,31 @@
 static void myri10ge_watchdog_timer(unsigned long arg)
 {
 	struct myri10ge_priv *mgp;
+	struct myri10ge_slice_state *ss;
 	u32 rx_pause_cnt;
 
 	mgp = (struct myri10ge_priv *)arg;
 
-	if (mgp->rx_small.watchdog_needed) {
-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
-					mgp->small_bytes + MXGEFW_PAD, 1);
-		if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt >=
-		    myri10ge_fill_thresh)
-			mgp->rx_small.watchdog_needed = 0;
-	}
-	if (mgp->rx_big.watchdog_needed) {
-		myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 1);
-		if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt >=
-		    myri10ge_fill_thresh)
-			mgp->rx_big.watchdog_needed = 0;
-	}
-	rx_pause_cnt = ntohl(mgp->fw_stats->dropped_pause);
+	rx_pause_cnt = ntohl(mgp->ss.fw_stats->dropped_pause);
 
-	if (mgp->tx.req != mgp->tx.done &&
-	    mgp->tx.done == mgp->watchdog_tx_done &&
-	    mgp->watchdog_tx_req != mgp->watchdog_tx_done) {
+	ss = &mgp->ss;
+	if (ss->rx_small.watchdog_needed) {
+		myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
+					mgp->small_bytes + MXGEFW_PAD, 1);
+		if (ss->rx_small.fill_cnt - ss->rx_small.cnt >=
+		    myri10ge_fill_thresh)
+			ss->rx_small.watchdog_needed = 0;
+	}
+	if (ss->rx_big.watchdog_needed) {
+		myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 1);
+		if (ss->rx_big.fill_cnt - ss->rx_big.cnt >=
+		    myri10ge_fill_thresh)
+			ss->rx_big.watchdog_needed = 0;
+	}
+
+	if (ss->tx.req != ss->tx.done &&
+	    ss->tx.done == ss->watchdog_tx_done &&
+	    ss->watchdog_tx_req != ss->watchdog_tx_done) {
 		/* nic seems like it might be stuck.. */
 		if (rx_pause_cnt != mgp->watchdog_pause) {
 			if (net_ratelimit())
@@ -3005,8 +3101,8 @@
 	/* rearm timer */
 	mod_timer(&mgp->watchdog_timer,
 		  jiffies + myri10ge_watchdog_timeout * HZ);
-	mgp->watchdog_tx_done = mgp->tx.done;
-	mgp->watchdog_tx_req = mgp->tx.req;
+	ss->watchdog_tx_done = ss->tx.done;
+	ss->watchdog_tx_req = ss->tx.req;
 	mgp->watchdog_pause = rx_pause_cnt;
 }
 
@@ -3030,7 +3126,7 @@
 
 	mgp = netdev_priv(netdev);
 	mgp->dev = netdev;
-	netif_napi_add(netdev, &mgp->napi, myri10ge_poll, myri10ge_napi_weight);
+	netif_napi_add(netdev, &mgp->ss.napi, myri10ge_poll, myri10ge_napi_weight);
 	mgp->pdev = pdev;
 	mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
 	mgp->pause = myri10ge_flow_control;
@@ -3076,9 +3172,9 @@
 	if (mgp->cmd == NULL)
 		goto abort_with_netdev;
 
-	mgp->fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
-					   &mgp->fw_stats_bus, GFP_KERNEL);
-	if (mgp->fw_stats == NULL)
+	mgp->ss.fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
+					   &mgp->ss.fw_stats_bus, GFP_KERNEL);
+	if (mgp->ss.fw_stats == NULL)
 		goto abort_with_cmd;
 
 	mgp->board_span = pci_resource_len(pdev, 0);
@@ -3118,12 +3214,12 @@
 		netdev->dev_addr[i] = mgp->mac_addr[i];
 
 	/* allocate rx done ring */
-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
-	mgp->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
-						&mgp->rx_done.bus, GFP_KERNEL);
-	if (mgp->rx_done.entry == NULL)
+	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
+	mgp->ss.rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
+						&mgp->ss.rx_done.bus, GFP_KERNEL);
+	if (mgp->ss.rx_done.entry == NULL)
 		goto abort_with_ioremap;
-	memset(mgp->rx_done.entry, 0, bytes);
+	memset(mgp->ss.rx_done.entry, 0, bytes);
 
 	myri10ge_select_firmware(mgp);
 
@@ -3183,7 +3279,7 @@
 	}
 	dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
 		 (mgp->msi_enabled ? "MSI" : "xPIC"),
-		 netdev->irq, mgp->tx.boundary, mgp->fw_name,
+		 netdev->irq, mgp->tx_boundary, mgp->fw_name,
 		 (mgp->wc_enabled ? "Enabled" : "Disabled"));
 
 	return 0;
@@ -3195,9 +3291,9 @@
 	myri10ge_dummy_rdma(mgp, 0);
 
 abort_with_rx_done:
-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
 	dma_free_coherent(&pdev->dev, bytes,
-			  mgp->rx_done.entry, mgp->rx_done.bus);
+			  mgp->ss.rx_done.entry, mgp->ss.rx_done.bus);
 
 abort_with_ioremap:
 	iounmap(mgp->sram);
@@ -3207,8 +3303,8 @@
 	if (mgp->mtrr >= 0)
 		mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
 #endif
-	dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
-			  mgp->fw_stats, mgp->fw_stats_bus);
+	dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
+			  mgp->ss.fw_stats, mgp->ss.fw_stats_bus);
 
 abort_with_cmd:
 	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
@@ -3246,9 +3342,9 @@
 	/* avoid a memory leak */
 	pci_restore_state(pdev);
 
-	bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry);
+	bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
 	dma_free_coherent(&pdev->dev, bytes,
-			  mgp->rx_done.entry, mgp->rx_done.bus);
+			  mgp->ss.rx_done.entry, mgp->ss.rx_done.bus);
 
 	iounmap(mgp->sram);
 
@@ -3256,8 +3352,8 @@
 	if (mgp->mtrr >= 0)
 		mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
 #endif
-	dma_free_coherent(&pdev->dev, sizeof(*mgp->fw_stats),
-			  mgp->fw_stats, mgp->fw_stats_bus);
+	dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
+			  mgp->ss.fw_stats, mgp->ss.fw_stats_bus);
 
 	dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
 			  mgp->cmd, mgp->cmd_bus);
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index 58e5717..fdbeeee 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -10,7 +10,7 @@
 	__be32 low;
 };
 
-/* 4 Bytes.  8 Bytes for NDIS drivers. */
+/* 4 Bytes */
 struct mcp_slot {
 	__sum16 checksum;
 	__be16 length;
@@ -144,6 +144,7 @@
 	 * a power of 2 number of entries.  */
 
 	MXGEFW_CMD_SET_INTRQ_SIZE,	/* in bytes */
+#define MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK  (1 << 31)
 
 	/* command to bring ethernet interface up.  Above parameters
 	 * (plus mtu & mac address) must have been exchanged prior
@@ -221,10 +222,14 @@
 	MXGEFW_CMD_GET_MAX_RSS_QUEUES,
 	MXGEFW_CMD_ENABLE_RSS_QUEUES,
 	/* data0 = number of slices n (0, 1, ..., n-1) to enable
-	 * data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue.
+	 * data1 = interrupt mode.
+	 * 0=share one INTx/MSI, 1=use one MSI-X per queue.
 	 * If all queues share one interrupt, the driver must have set
 	 * RSS_SHARED_INTERRUPT_DMA before enabling queues.
 	 */
+#define MXGEFW_SLICE_INTR_MODE_SHARED 0
+#define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE 1
+
 	MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
 	MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
 	/* data0, data1 = bus address lsw, msw */
@@ -241,10 +246,14 @@
 	 * 0: disable rss.  nic does not distribute receive packets.
 	 * 1: enable rss.  nic distributes receive packets among queues.
 	 * data1 = hash type
-	 * 1: IPV4
-	 * 2: TCP_IPV4
-	 * 3: IPV4 | TCP_IPV4
+	 * 1: IPV4            (required by RSS)
+	 * 2: TCP_IPV4        (required by RSS)
+	 * 3: IPV4 | TCP_IPV4 (required by RSS)
+	 * 4: source port
 	 */
+#define MXGEFW_RSS_HASH_TYPE_IPV4      0x1
+#define MXGEFW_RSS_HASH_TYPE_TCP_IPV4  0x2
+#define MXGEFW_RSS_HASH_TYPE_SRC_PORT  0x4
 
 	MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
 	/* Return data = the max. size of the entire headers of a IPv6 TSO packet.
@@ -260,6 +269,8 @@
 	 * 0: Linux/FreeBSD style (NIC default)
 	 * 1: NDIS/NetBSD style
 	 */
+#define MXGEFW_TSO_MODE_LINUX  0
+#define MXGEFW_TSO_MODE_NDIS   1
 
 	MXGEFW_CMD_MDIO_READ,
 	/* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */
@@ -286,6 +297,38 @@
 	/* Return data = NIC memory offset of mcp_vpump_public_global */
 	MXGEFW_CMD_RESET_VPUMP,
 	/* Resets the VPUMP state */
+
+	MXGEFW_CMD_SET_RSS_MCP_SLOT_TYPE,
+	/* data0 = mcp_slot type to use.
+	 * 0 = the default 4B mcp_slot
+	 * 1 = 8B mcp_slot_8
+	 */
+#define MXGEFW_RSS_MCP_SLOT_TYPE_MIN        0
+#define MXGEFW_RSS_MCP_SLOT_TYPE_WITH_HASH  1
+
+	MXGEFW_CMD_SET_THROTTLE_FACTOR,
+	/* set the throttle factor for ethp_z8e
+	 * data0 = throttle_factor
+	 * throttle_factor = 256 * pcie-raw-speed / tx_speed
+	 * tx_speed = 256 * pcie-raw-speed / throttle_factor
+	 *
+	 * For PCI-E x8: pcie-raw-speed == 16Gb/s
+	 * For PCI-E x4: pcie-raw-speed == 8Gb/s
+	 *
+	 * ex1: throttle_factor == 0x1a0 (416), tx_speed == 1.23GB/s == 9.846 Gb/s
+	 * ex2: throttle_factor == 0x200 (512), tx_speed == 1.0GB/s == 8 Gb/s
+	 *
+	 * with tx_boundary == 2048, max-throttle-factor == 8191 => min-speed == 500Mb/s
+	 * with tx_boundary == 4096, max-throttle-factor == 4095 => min-speed == 1Gb/s
+	 */
+
+	MXGEFW_CMD_VPUMP_UP,
+	/* Allocates VPump Connection, Send Request and Zero copy buffer address tables */
+	MXGEFW_CMD_GET_VPUMP_CLK,
+	/* Get the lanai clock */
+
+	MXGEFW_CMD_GET_DCA_OFFSET,
+	/* offset of dca control for WDMAs */
 };
 
 enum myri10ge_mcp_cmd_status {
@@ -302,7 +345,8 @@
 	MXGEFW_CMD_ERROR_UNALIGNED,
 	MXGEFW_CMD_ERROR_NO_MDIO,
 	MXGEFW_CMD_ERROR_XFP_FAILURE,
-	MXGEFW_CMD_ERROR_XFP_ABSENT
+	MXGEFW_CMD_ERROR_XFP_ABSENT,
+	MXGEFW_CMD_ERROR_BAD_PCIE_LINK
 };
 
 #define MXGEFW_OLD_IRQ_DATA_LEN 40
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
index 16a810d..07d65c2 100644
--- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
@@ -1,30 +1,6 @@
 #ifndef __MYRI10GE_MCP_GEN_HEADER_H__
 #define __MYRI10GE_MCP_GEN_HEADER_H__
 
-/* this file define a standard header used as a first entry point to
- * exchange information between firmware/driver and driver.  The
- * header structure can be anywhere in the mcp. It will usually be in
- * the .data section, because some fields needs to be initialized at
- * compile time.
- * The 32bit word at offset MX_HEADER_PTR_OFFSET in the mcp must
- * contains the location of the header.
- *
- * Typically a MCP will start with the following:
- * .text
- * .space 52    ! to help catch MEMORY_INT errors
- * bt start     ! jump to real code
- * nop
- * .long _gen_mcp_header
- *
- * The source will have a definition like:
- *
- * mcp_gen_header_t gen_mcp_header = {
- * .header_length = sizeof(mcp_gen_header_t),
- * .mcp_type = MCP_TYPE_XXX,
- * .version = "something $Id: mcp_gen_header.h,v 1.2 2006/05/13 10:04:35 bgoglin Exp $",
- * .mcp_globals = (unsigned)&Globals
- * };
- */
 
 #define MCP_HEADER_PTR_OFFSET  0x3c
 
@@ -32,13 +8,14 @@
 #define MCP_TYPE_PCIE 0x70636965	/* "PCIE" pcie-only MCP */
 #define MCP_TYPE_ETH 0x45544820	/* "ETH " */
 #define MCP_TYPE_MCP0 0x4d435030	/* "MCP0" */
+#define MCP_TYPE_DFLT 0x20202020	/* "    " */
 
 struct mcp_gen_header {
 	/* the first 4 fields are filled at compile time */
 	unsigned header_length;
 	__be32 mcp_type;
 	char version[128];
-	unsigned mcp_globals;	/* pointer to mcp-type specific structure */
+	unsigned mcp_private;	/* pointer to mcp-type specific structure */
 
 	/* filled by the MCP at run-time */
 	unsigned sram_size;
@@ -53,6 +30,18 @@
 	 *
 	 * Never remove any field.  Keep everything naturally align.
 	 */
+
+	/* Specifies if the running mcp is mcp0, 1, or 2. */
+	unsigned char mcp_index;
+	unsigned char disable_rabbit;
+	unsigned char unaligned_tlp;
+	unsigned char pad1;
+	unsigned counters_addr;
+	unsigned copy_block_info;	/* for small mcps loaded with "lload -d" */
+	unsigned short handoff_id_major;	/* must be equal */
+	unsigned short handoff_id_caps;	/* bitfield: new mcp must have superset */
+	unsigned msix_table_addr;	/* start address of msix table in firmware */
+	/* 8 */
 };
 
 #endif				/* __MYRI10GE_MCP_GEN_HEADER_H__ */
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 4009c4c..918f802 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -1,6 +1,6 @@
 /* niu.c: Neptune ethernet driver.
  *
- * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/module.h>
@@ -33,8 +33,8 @@
 
 #define DRV_MODULE_NAME		"niu"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.8"
-#define DRV_MODULE_RELDATE	"April 24, 2008"
+#define DRV_MODULE_VERSION	"0.9"
+#define DRV_MODULE_RELDATE	"May 4, 2008"
 
 static char version[] __devinitdata =
 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -865,7 +865,6 @@
 	return 0;
 }
 
-
 static int link_status_10g_serdes(struct niu *np, int *link_up_p)
 {
 	unsigned long flags;
@@ -900,7 +899,6 @@
 	return 0;
 }
 
-
 static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
 {
 	struct niu_link_config *lp = &np->link_config;
@@ -957,7 +955,6 @@
 	return err;
 }
 
-
 static int bcm8704_reset(struct niu *np)
 {
 	int err, limit;
@@ -1357,8 +1354,6 @@
 	return 0;
 }
 
-
-
 static int xcvr_init_1g_rgmii(struct niu *np)
 {
 	int err;
@@ -1419,7 +1414,6 @@
 	return 0;
 }
 
-
 static int mii_init_common(struct niu *np)
 {
 	struct niu_link_config *lp = &np->link_config;
@@ -7008,31 +7002,20 @@
 	return 0;
 }
 
-/* niu board models have a trailing dash version incremented
- * with HW rev change. Need to ingnore the  dash version while
- * checking for match
- *
- * for example, for the 10G card the current vpd.board_model
- * is 501-5283-04, of which -04 is the  dash version and have
- * to be ignored
- */
-static int niu_board_model_match(struct niu *np, const char *model)
-{
-	return !strncmp(np->vpd.board_model, model, strlen(model));
-}
-
 static int niu_pci_vpd_get_nports(struct niu *np)
 {
 	int ports = 0;
 
-	if ((niu_board_model_match(np, NIU_QGC_LP_BM_STR)) ||
-	    (niu_board_model_match(np, NIU_QGC_PEM_BM_STR)) ||
-	    (niu_board_model_match(np, NIU_ALONSO_BM_STR))) {
+	if ((!strcmp(np->vpd.model, NIU_QGC_LP_MDL_STR)) ||
+	    (!strcmp(np->vpd.model, NIU_QGC_PEM_MDL_STR)) ||
+	    (!strcmp(np->vpd.model, NIU_MARAMBA_MDL_STR)) ||
+	    (!strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) ||
+	    (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR))) {
 		ports = 4;
-	} else if ((niu_board_model_match(np, NIU_2XGF_LP_BM_STR)) ||
-		   (niu_board_model_match(np, NIU_2XGF_PEM_BM_STR)) ||
-		   (niu_board_model_match(np, NIU_FOXXY_BM_STR)) ||
-		   (niu_board_model_match(np, NIU_2XGF_MRVL_BM_STR))) {
+	} else if ((!strcmp(np->vpd.model, NIU_2XGF_LP_MDL_STR)) ||
+		   (!strcmp(np->vpd.model, NIU_2XGF_PEM_MDL_STR)) ||
+		   (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) ||
+		   (!strcmp(np->vpd.model, NIU_2XGF_MRVL_MDL_STR))) {
 		ports = 2;
 	}
 
@@ -7053,8 +7036,8 @@
 		return;
 	}
 
-	if (!strcmp(np->vpd.model, "SUNW,CP3220") ||
-	    !strcmp(np->vpd.model, "SUNW,CP3260")) {
+	if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) ||
+	    !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) {
 		np->flags |= NIU_FLAGS_10G;
 		np->flags &= ~NIU_FLAGS_FIBER;
 		np->flags |= NIU_FLAGS_XCVR_SERDES;
@@ -7065,7 +7048,7 @@
 		}
 		if (np->flags & NIU_FLAGS_10G)
 			 np->mac_xcvr = MAC_XCVR_XPCS;
-	} else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) {
+	} else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) {
 		np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER |
 			      NIU_FLAGS_HOTPLUG_PHY);
 	} else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) {
@@ -7264,8 +7247,11 @@
 				parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) &
 					ESPC_NUM_PORTS_MACS_VAL;
 
+				/* All of the current probing methods fail on
+				 * Maramba on-board parts.
+				 */
 				if (!parent->num_ports)
-					return -ENODEV;
+					parent->num_ports = 4;
 			}
 		}
 	}
@@ -7538,8 +7524,8 @@
 	u32 val;
 	int err;
 
-	if (!strcmp(np->vpd.model, "SUNW,CP3220") ||
-	    !strcmp(np->vpd.model, "SUNW,CP3260")) {
+	if (!strcmp(np->vpd.model, NIU_ALONSO_MDL_STR) ||
+	    !strcmp(np->vpd.model, NIU_KIMI_MDL_STR)) {
 		num_10g = 0;
 		num_1g = 2;
 		parent->plat_type = PLAT_TYPE_ATCA_CP3220;
@@ -7548,7 +7534,7 @@
 		       phy_encode(PORT_TYPE_1G, 1) |
 		       phy_encode(PORT_TYPE_1G, 2) |
 		       phy_encode(PORT_TYPE_1G, 3));
-	} else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) {
+	} else if (!strcmp(np->vpd.model, NIU_FOXXY_MDL_STR)) {
 		num_10g = 2;
 		num_1g = 0;
 		parent->num_ports = 2;
@@ -7943,6 +7929,7 @@
 	struct device_node *dp;
 	const char *phy_type;
 	const u8 *mac_addr;
+	const char *model;
 	int prop_len;
 
 	if (np->parent->plat_type == PLAT_TYPE_NIU)
@@ -7997,6 +7984,11 @@
 
 	memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len);
 
+	model = of_get_property(dp, "model", &prop_len);
+
+	if (model)
+		strcpy(np->vpd.model, model);
+
 	return 0;
 #else
 	return -EINVAL;
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 101a3f1..c6fa883 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -2946,6 +2946,15 @@
 #define	NIU_ALONSO_BM_STR	"373-0202"
 #define	NIU_FOXXY_BM_STR	"501-7961"
 #define	NIU_2XGF_MRVL_BM_STR	"SK-6E82"
+#define	NIU_QGC_LP_MDL_STR	"SUNW,pcie-qgc"
+#define	NIU_2XGF_LP_MDL_STR	"SUNW,pcie-2xgf"
+#define	NIU_QGC_PEM_MDL_STR	"SUNW,pcie-qgc-pem"
+#define	NIU_2XGF_PEM_MDL_STR	"SUNW,pcie-2xgf-pem"
+#define	NIU_ALONSO_MDL_STR	"SUNW,CP3220"
+#define	NIU_KIMI_MDL_STR	"SUNW,CP3260"
+#define	NIU_MARAMBA_MDL_STR	"SUNW,pcie-neptune"
+#define	NIU_FOXXY_MDL_STR	"SUNW,pcie-rfem"
+#define	NIU_2XGF_MRVL_MDL_STR	"SysKonnect,pcie-2xgf"
 
 #define NIU_VPD_MIN_MAJOR	3
 #define NIU_VPD_MIN_MINOR	4
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index d0d5585..81fd852 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,12 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME	"pcnet32"
-#ifdef CONFIG_PCNET32_NAPI
-#define DRV_VERSION	"1.34-NAPI"
-#else
-#define DRV_VERSION	"1.34"
-#endif
-#define DRV_RELDATE	"14.Aug.2007"
+#define DRV_VERSION	"1.35"
+#define DRV_RELDATE	"21.Apr.2008"
 #define PFX		DRV_NAME ": "
 
 static const char *const version =
@@ -445,30 +441,24 @@
 
 static void pcnet32_netif_stop(struct net_device *dev)
 {
-#ifdef CONFIG_PCNET32_NAPI
 	struct pcnet32_private *lp = netdev_priv(dev);
-#endif
+
 	dev->trans_start = jiffies;
-#ifdef CONFIG_PCNET32_NAPI
 	napi_disable(&lp->napi);
-#endif
 	netif_tx_disable(dev);
 }
 
 static void pcnet32_netif_start(struct net_device *dev)
 {
-#ifdef CONFIG_PCNET32_NAPI
 	struct pcnet32_private *lp = netdev_priv(dev);
 	ulong ioaddr = dev->base_addr;
 	u16 val;
-#endif
+
 	netif_wake_queue(dev);
-#ifdef CONFIG_PCNET32_NAPI
 	val = lp->a.read_csr(ioaddr, CSR3);
 	val &= 0x00ff;
 	lp->a.write_csr(ioaddr, CSR3, val);
 	napi_enable(&lp->napi);
-#endif
 }
 
 /*
@@ -911,11 +901,7 @@
 	rc = 1;			/* default to fail */
 
 	if (netif_running(dev))
-#ifdef CONFIG_PCNET32_NAPI
 		pcnet32_netif_stop(dev);
-#else
-		pcnet32_close(dev);
-#endif
 
 	spin_lock_irqsave(&lp->lock, flags);
 	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
@@ -1046,7 +1032,6 @@
 	x = a->read_bcr(ioaddr, 32);	/* reset internal loopback */
 	a->write_bcr(ioaddr, 32, (x & ~0x0002));
 
-#ifdef CONFIG_PCNET32_NAPI
 	if (netif_running(dev)) {
 		pcnet32_netif_start(dev);
 		pcnet32_restart(dev, CSR0_NORMAL);
@@ -1055,16 +1040,6 @@
 		lp->a.write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
 	}
 	spin_unlock_irqrestore(&lp->lock, flags);
-#else
-	if (netif_running(dev)) {
-		spin_unlock_irqrestore(&lp->lock, flags);
-		pcnet32_open(dev);
-	} else {
-		pcnet32_purge_rx_ring(dev);
-		lp->a.write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
-		spin_unlock_irqrestore(&lp->lock, flags);
-	}
-#endif
 
 	return (rc);
 }				/* end pcnet32_loopback_test  */
@@ -1270,11 +1245,7 @@
 	}
 	dev->stats.rx_bytes += skb->len;
 	skb->protocol = eth_type_trans(skb, dev);
-#ifdef CONFIG_PCNET32_NAPI
 	netif_receive_skb(skb);
-#else
-	netif_rx(skb);
-#endif
 	dev->last_rx = jiffies;
 	dev->stats.rx_packets++;
 	return;
@@ -1403,7 +1374,6 @@
 	return must_restart;
 }
 
-#ifdef CONFIG_PCNET32_NAPI
 static int pcnet32_poll(struct napi_struct *napi, int budget)
 {
 	struct pcnet32_private *lp = container_of(napi, struct pcnet32_private, napi);
@@ -1442,7 +1412,6 @@
 	}
 	return work_done;
 }
-#endif
 
 #define PCNET32_REGS_PER_PHY	32
 #define PCNET32_MAX_PHYS	32
@@ -1864,9 +1833,7 @@
 	/* napi.weight is used in both the napi and non-napi cases */
 	lp->napi.weight = lp->rx_ring_size / 2;
 
-#ifdef CONFIG_PCNET32_NAPI
 	netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2);
-#endif
 
 	if (fdx && !(lp->options & PCNET32_PORT_ASEL) &&
 	    ((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
@@ -2297,9 +2264,7 @@
 		goto err_free_ring;
 	}
 
-#ifdef CONFIG_PCNET32_NAPI
 	napi_enable(&lp->napi);
-#endif
 
 	/* Re-initialize the PCNET32, and start it when done. */
 	lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
@@ -2623,7 +2588,6 @@
 				       dev->name, csr0);
 			/* unlike for the lance, there is no restart needed */
 		}
-#ifdef CONFIG_PCNET32_NAPI
 		if (netif_rx_schedule_prep(dev, &lp->napi)) {
 			u16 val;
 			/* set interrupt masks */
@@ -2634,24 +2598,9 @@
 			__netif_rx_schedule(dev, &lp->napi);
 			break;
 		}
-#else
-		pcnet32_rx(dev, lp->napi.weight);
-		if (pcnet32_tx(dev)) {
-			/* reset the chip to clear the error condition, then restart */
-			lp->a.reset(ioaddr);
-			lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
-			pcnet32_restart(dev, CSR0_START);
-			netif_wake_queue(dev);
-		}
-#endif
 		csr0 = lp->a.read_csr(ioaddr, CSR0);
 	}
 
-#ifndef CONFIG_PCNET32_NAPI
-	/* Set interrupt enable. */
-	lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
-#endif
-
 	if (netif_msg_intr(lp))
 		printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
 		       dev->name, lp->a.read_csr(ioaddr, CSR0));
@@ -2670,9 +2619,7 @@
 	del_timer_sync(&lp->watchdog_timer);
 
 	netif_stop_queue(dev);
-#ifdef CONFIG_PCNET32_NAPI
 	napi_disable(&lp->napi);
-#endif
 
 	spin_lock_irqsave(&lp->lock, flags);
 
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3c18bb5..45cc291 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -547,7 +547,7 @@
  * Must not be called from interrupt context, or while the
  * phydev->lock is held.
  */
-void phy_error(struct phy_device *phydev)
+static void phy_error(struct phy_device *phydev)
 {
 	mutex_lock(&phydev->lock);
 	phydev->state = PHY_HALTED;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index d3207c0..1f4ca2b 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2458,6 +2458,7 @@
 
 out3:
 	atomic_dec(&ppp_unit_count);
+	unregister_netdev(dev);
 out2:
 	mutex_unlock(&all_ppp_mutex);
 	free_netdev(dev);
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 244d783..79359919 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -1621,9 +1621,16 @@
 end:
 	release_sock(sk);
 
-	if (error != 0)
-		PRINTK(session ? session->debug : -1, PPPOL2TP_MSG_CONTROL, KERN_WARNING,
-		       "%s: connect failed: %d\n", session->name, error);
+	if (error != 0) {
+		if (session)
+			PRINTK(session->debug,
+				PPPOL2TP_MSG_CONTROL, KERN_WARNING,
+				"%s: connect failed: %d\n",
+				session->name, error);
+		else
+			PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_WARNING,
+				"connect failed: %d\n", error);
+	}
 
 	return error;
 }
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 0d32123..1dae1f2 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2474,6 +2474,8 @@
 
 	pr_debug("%s: <-\n", __func__);
 
+	free_page((unsigned long)wl->buf);
+
 	pr_debug("%s: destroy queues\n", __func__);
 	destroy_workqueue(wl->eurus_cmd_queue);
 	destroy_workqueue(wl->event_queue);
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index 0f02344..1d2daee 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -1,5 +1,5 @@
 sfc-y			+= efx.o falcon.o tx.o rx.o falcon_xmac.o \
-			   i2c-direct.o ethtool.o xfp_phy.o mdio_10g.o \
-			   tenxpress.o boards.o sfe4001.o
+			   i2c-direct.o selftest.o ethtool.o xfp_phy.o \
+			   mdio_10g.o tenxpress.o boards.o sfe4001.o
 
 obj-$(CONFIG_SFC)	+= sfc.o
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index f56341d..695764d 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -22,5 +22,7 @@
 extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info);
 extern int sfe4001_poweron(struct efx_nic *efx);
 extern void sfe4001_poweroff(struct efx_nic *efx);
+/* Are we putting the PHY into flash config mode */
+extern unsigned int sfe4001_phy_flash_cfg;
 
 #endif
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 59edcf7..418f2e5 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1873,6 +1873,7 @@
 		tx_queue->queue = i;
 		tx_queue->buffer = NULL;
 		tx_queue->channel = &efx->channel[0]; /* for safety */
+		tx_queue->tso_headers_free = NULL;
 	}
 	for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
 		rx_queue = &efx->rx_queue[i];
@@ -2071,7 +2072,8 @@
 	net_dev = alloc_etherdev(sizeof(*efx));
 	if (!net_dev)
 		return -ENOMEM;
-	net_dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA;
+	net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
+			      NETIF_F_HIGHDMA | NETIF_F_TSO);
 	if (lro)
 		net_dev->features |= NETIF_F_LRO;
 	efx = net_dev->priv;
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h
index 43663a4..c53290d 100644
--- a/drivers/net/sfc/enum.h
+++ b/drivers/net/sfc/enum.h
@@ -10,6 +10,55 @@
 #ifndef EFX_ENUM_H
 #define EFX_ENUM_H
 
+/**
+ * enum efx_loopback_mode - loopback modes
+ * @LOOPBACK_NONE: no loopback
+ * @LOOPBACK_XGMII: loopback within MAC at XGMII level
+ * @LOOPBACK_XGXS: loopback within MAC at XGXS level
+ * @LOOPBACK_XAUI: loopback within MAC at XAUI level
+ * @LOOPBACK_PHYXS: loopback within PHY at PHYXS level
+ * @LOOPBACK_PCS: loopback within PHY at PCS level
+ * @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level
+ * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!)
+ */
+/* Please keep in order and up-to-date w.r.t the following two #defines */
+enum efx_loopback_mode {
+	LOOPBACK_NONE = 0,
+	LOOPBACK_MAC = 1,
+	LOOPBACK_XGMII = 2,
+	LOOPBACK_XGXS = 3,
+	LOOPBACK_XAUI = 4,
+	LOOPBACK_PHY = 5,
+	LOOPBACK_PHYXS = 6,
+	LOOPBACK_PCS = 7,
+	LOOPBACK_PMAPMD = 8,
+	LOOPBACK_NETWORK = 9,
+	LOOPBACK_MAX
+};
+
+#define LOOPBACK_TEST_MAX LOOPBACK_PMAPMD
+
+extern const char *efx_loopback_mode_names[];
+#define LOOPBACK_MODE_NAME(mode)			\
+	STRING_TABLE_LOOKUP(mode, efx_loopback_mode)
+#define LOOPBACK_MODE(efx)				\
+	LOOPBACK_MODE_NAME(efx->loopback_mode)
+
+/* These loopbacks occur within the controller */
+#define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \
+				(1 << LOOPBACK_XGXS) | \
+				(1 << LOOPBACK_XAUI))
+
+#define LOOPBACK_MASK(_efx)			\
+	(1 << (_efx)->loopback_mode)
+
+#define LOOPBACK_INTERNAL(_efx)						\
+	((LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx)) ? 1 : 0)
+
+#define LOOPBACK_OUT_OF(_from, _to, _mask)		\
+	(((LOOPBACK_MASK(_from) & (_mask)) &&		\
+	  ((LOOPBACK_MASK(_to) & (_mask)) == 0)) ? 1 : 0)
+
 /*****************************************************************************/
 
 /**
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index ad541ba..e2c75d1 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -12,12 +12,26 @@
 #include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include "net_driver.h"
+#include "selftest.h"
 #include "efx.h"
 #include "ethtool.h"
 #include "falcon.h"
 #include "gmii.h"
 #include "mac.h"
 
+const char *efx_loopback_mode_names[] = {
+	[LOOPBACK_NONE]		= "NONE",
+	[LOOPBACK_MAC]		= "MAC",
+	[LOOPBACK_XGMII]	= "XGMII",
+	[LOOPBACK_XGXS]		= "XGXS",
+	[LOOPBACK_XAUI] 	= "XAUI",
+	[LOOPBACK_PHY]		= "PHY",
+	[LOOPBACK_PHYXS]	= "PHY(XS)",
+	[LOOPBACK_PCS]	 	= "PHY(PCS)",
+	[LOOPBACK_PMAPMD]	= "PHY(PMAPMD)",
+	[LOOPBACK_NETWORK]	= "NETWORK",
+};
+
 static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable);
 
 struct ethtool_string {
@@ -217,23 +231,179 @@
 	strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info));
 }
 
+/**
+ * efx_fill_test - fill in an individual self-test entry
+ * @test_index:		Index of the test
+ * @strings:		Ethtool strings, or %NULL
+ * @data:		Ethtool test results, or %NULL
+ * @test:		Pointer to test result (used only if data != %NULL)
+ * @unit_format:	Unit name format (e.g. "channel\%d")
+ * @unit_id:		Unit id (e.g. 0 for "channel0")
+ * @test_format:	Test name format (e.g. "loopback.\%s.tx.sent")
+ * @test_id:		Test id (e.g. "PHY" for "loopback.PHY.tx_sent")
+ *
+ * Fill in an individual self-test entry.
+ */
+static void efx_fill_test(unsigned int test_index,
+			  struct ethtool_string *strings, u64 *data,
+			  int *test, const char *unit_format, int unit_id,
+			  const char *test_format, const char *test_id)
+{
+	struct ethtool_string unit_str, test_str;
+
+	/* Fill data value, if applicable */
+	if (data)
+		data[test_index] = *test;
+
+	/* Fill string, if applicable */
+	if (strings) {
+		snprintf(unit_str.name, sizeof(unit_str.name),
+			 unit_format, unit_id);
+		snprintf(test_str.name, sizeof(test_str.name),
+			 test_format, test_id);
+		snprintf(strings[test_index].name,
+			 sizeof(strings[test_index].name),
+			 "%-9s%-17s", unit_str.name, test_str.name);
+	}
+}
+
+#define EFX_PORT_NAME "port%d", 0
+#define EFX_CHANNEL_NAME(_channel) "channel%d", _channel->channel
+#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue
+#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue
+#define EFX_LOOPBACK_NAME(_mode, _counter)			\
+	"loopback.%s." _counter, LOOPBACK_MODE_NAME(mode)
+
+/**
+ * efx_fill_loopback_test - fill in a block of loopback self-test entries
+ * @efx:		Efx NIC
+ * @lb_tests:		Efx loopback self-test results structure
+ * @mode:		Loopback test mode
+ * @test_index:		Starting index of the test
+ * @strings:		Ethtool strings, or %NULL
+ * @data:		Ethtool test results, or %NULL
+ */
+static int efx_fill_loopback_test(struct efx_nic *efx,
+				  struct efx_loopback_self_tests *lb_tests,
+				  enum efx_loopback_mode mode,
+				  unsigned int test_index,
+				  struct ethtool_string *strings, u64 *data)
+{
+	struct efx_tx_queue *tx_queue;
+
+	efx_for_each_tx_queue(tx_queue, efx) {
+		efx_fill_test(test_index++, strings, data,
+			      &lb_tests->tx_sent[tx_queue->queue],
+			      EFX_TX_QUEUE_NAME(tx_queue),
+			      EFX_LOOPBACK_NAME(mode, "tx_sent"));
+		efx_fill_test(test_index++, strings, data,
+			      &lb_tests->tx_done[tx_queue->queue],
+			      EFX_TX_QUEUE_NAME(tx_queue),
+			      EFX_LOOPBACK_NAME(mode, "tx_done"));
+	}
+	efx_fill_test(test_index++, strings, data,
+		      &lb_tests->rx_good,
+		      EFX_PORT_NAME,
+		      EFX_LOOPBACK_NAME(mode, "rx_good"));
+	efx_fill_test(test_index++, strings, data,
+		      &lb_tests->rx_bad,
+		      EFX_PORT_NAME,
+		      EFX_LOOPBACK_NAME(mode, "rx_bad"));
+
+	return test_index;
+}
+
+/**
+ * efx_ethtool_fill_self_tests - get self-test details
+ * @efx:		Efx NIC
+ * @tests:		Efx self-test results structure, or %NULL
+ * @strings:		Ethtool strings, or %NULL
+ * @data:		Ethtool test results, or %NULL
+ */
+static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
+				       struct efx_self_tests *tests,
+				       struct ethtool_string *strings,
+				       u64 *data)
+{
+	struct efx_channel *channel;
+	unsigned int n = 0;
+	enum efx_loopback_mode mode;
+
+	/* Interrupt */
+	efx_fill_test(n++, strings, data, &tests->interrupt,
+		      "core", 0, "interrupt", NULL);
+
+	/* Event queues */
+	efx_for_each_channel(channel, efx) {
+		efx_fill_test(n++, strings, data,
+			      &tests->eventq_dma[channel->channel],
+			      EFX_CHANNEL_NAME(channel),
+			      "eventq.dma", NULL);
+		efx_fill_test(n++, strings, data,
+			      &tests->eventq_int[channel->channel],
+			      EFX_CHANNEL_NAME(channel),
+			      "eventq.int", NULL);
+		efx_fill_test(n++, strings, data,
+			      &tests->eventq_poll[channel->channel],
+			      EFX_CHANNEL_NAME(channel),
+			      "eventq.poll", NULL);
+	}
+
+	/* PHY presence */
+	efx_fill_test(n++, strings, data, &tests->phy_ok,
+		      EFX_PORT_NAME, "phy_ok", NULL);
+
+	/* Loopback tests */
+	efx_fill_test(n++, strings, data, &tests->loopback_speed,
+		      EFX_PORT_NAME, "loopback.speed", NULL);
+	efx_fill_test(n++, strings, data, &tests->loopback_full_duplex,
+		      EFX_PORT_NAME, "loopback.full_duplex", NULL);
+	for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) {
+		if (!(efx->loopback_modes & (1 << mode)))
+			continue;
+		n = efx_fill_loopback_test(efx,
+					   &tests->loopback[mode], mode, n,
+					   strings, data);
+	}
+
+	return n;
+}
+
 static int efx_ethtool_get_stats_count(struct net_device *net_dev)
 {
 	return EFX_ETHTOOL_NUM_STATS;
 }
 
+static int efx_ethtool_self_test_count(struct net_device *net_dev)
+{
+	struct efx_nic *efx = net_dev->priv;
+
+	return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL);
+}
+
 static void efx_ethtool_get_strings(struct net_device *net_dev,
 				    u32 string_set, u8 *strings)
 {
+	struct efx_nic *efx = net_dev->priv;
 	struct ethtool_string *ethtool_strings =
 		(struct ethtool_string *)strings;
 	int i;
 
-	if (string_set == ETH_SS_STATS)
+	switch (string_set) {
+	case ETH_SS_STATS:
 		for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++)
 			strncpy(ethtool_strings[i].name,
 				efx_ethtool_stats[i].name,
 				sizeof(ethtool_strings[i].name));
+		break;
+	case ETH_SS_TEST:
+		efx_ethtool_fill_self_tests(efx, NULL,
+					    ethtool_strings, NULL);
+		break;
+	default:
+		/* No other string sets */
+		break;
+	}
 }
 
 static void efx_ethtool_get_stats(struct net_device *net_dev,
@@ -272,6 +442,22 @@
 	}
 }
 
+static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
+{
+	int rc;
+
+	/* Our TSO requires TX checksumming, so force TX checksumming
+	 * on when TSO is enabled.
+	 */
+	if (enable) {
+		rc = efx_ethtool_set_tx_csum(net_dev, 1);
+		if (rc)
+			return rc;
+	}
+
+	return ethtool_op_set_tso(net_dev, enable);
+}
+
 static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
 {
 	struct efx_nic *efx = net_dev->priv;
@@ -283,6 +469,15 @@
 
 	efx_flush_queues(efx);
 
+	/* Our TSO requires TX checksumming, so disable TSO when
+	 * checksumming is disabled
+	 */
+	if (!enable) {
+		rc = efx_ethtool_set_tso(net_dev, 0);
+		if (rc)
+			return rc;
+	}
+
 	return 0;
 }
 
@@ -305,6 +500,64 @@
 	return efx->rx_checksum_enabled;
 }
 
+static void efx_ethtool_self_test(struct net_device *net_dev,
+				  struct ethtool_test *test, u64 *data)
+{
+	struct efx_nic *efx = net_dev->priv;
+	struct efx_self_tests efx_tests;
+	int offline, already_up;
+	int rc;
+
+	ASSERT_RTNL();
+	if (efx->state != STATE_RUNNING) {
+		rc = -EIO;
+		goto fail1;
+	}
+
+	/* We need rx buffers and interrupts. */
+	already_up = (efx->net_dev->flags & IFF_UP);
+	if (!already_up) {
+		rc = dev_open(efx->net_dev);
+		if (rc) {
+			EFX_ERR(efx, "failed opening device.\n");
+			goto fail2;
+		}
+	}
+
+	memset(&efx_tests, 0, sizeof(efx_tests));
+	offline = (test->flags & ETH_TEST_FL_OFFLINE);
+
+	/* Perform online self tests first */
+	rc = efx_online_test(efx, &efx_tests);
+	if (rc)
+		goto out;
+
+	/* Perform offline tests only if online tests passed */
+	if (offline) {
+		/* Stop the kernel from sending packets during the test. */
+		efx_stop_queue(efx);
+		rc = efx_flush_queues(efx);
+		if (!rc)
+			rc = efx_offline_test(efx, &efx_tests,
+					      efx->loopback_modes);
+		efx_wake_queue(efx);
+	}
+
+ out:
+	if (!already_up)
+		dev_close(efx->net_dev);
+
+	EFX_LOG(efx, "%s all %sline self-tests\n",
+		rc == 0 ? "passed" : "failed", offline ? "off" : "on");
+
+ fail2:
+ fail1:
+	/* Fill ethtool results structures */
+	efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data);
+	if (rc)
+		test->flags |= ETH_TEST_FL_FAILED;
+}
+
 /* Restart autonegotiation */
 static int efx_ethtool_nway_reset(struct net_device *net_dev)
 {
@@ -451,8 +704,12 @@
 	.set_tx_csum		= efx_ethtool_set_tx_csum,
 	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
+	.get_tso		= ethtool_op_get_tso,
+	.set_tso		= efx_ethtool_set_tso,
 	.get_flags		= ethtool_op_get_flags,
 	.set_flags		= ethtool_op_set_flags,
+	.self_test_count	= efx_ethtool_self_test_count,
+	.self_test		= efx_ethtool_self_test,
 	.get_strings		= efx_ethtool_get_strings,
 	.phys_id		= efx_ethtool_phys_id,
 	.get_stats_count	= efx_ethtool_get_stats_count,
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 46db549..b57cc68 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1129,6 +1129,7 @@
 	case RX_RECOVERY_EV_DECODE:
 		EFX_ERR(efx, "channel %d seen DRIVER RX_RESET event. "
 			"Resetting.\n", channel->channel);
+		atomic_inc(&efx->rx_reset);
 		efx_schedule_reset(efx,
 				   EFX_WORKAROUND_6555(efx) ?
 				   RESET_TYPE_RX_RECOVERY :
@@ -1731,7 +1732,8 @@
 	efx_oword_t temp;
 	int count;
 
-	if (FALCON_REV(efx) < FALCON_REV_B0)
+	if ((FALCON_REV(efx) < FALCON_REV_B0) ||
+	    (efx->loopback_mode != LOOPBACK_NONE))
 		return;
 
 	falcon_read(efx, &temp, MAC0_CTRL_REG_KER);
@@ -2091,6 +2093,8 @@
 			efx->phy_type);
 		return -1;
 	}
+
+	efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks;
 	return 0;
 }
 
@@ -2468,14 +2472,12 @@
  fail5:
 	falcon_free_buffer(efx, &efx->irq_status);
  fail4:
-	/* fall-thru */
  fail3:
 	if (nic_data->pci_dev2) {
 		pci_dev_put(nic_data->pci_dev2);
 		nic_data->pci_dev2 = NULL;
 	}
  fail2:
-	/* fall-thru */
  fail1:
 	kfree(efx->nic_data);
 	return rc;
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index 0485a63..06e2d68 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -636,6 +636,14 @@
 #define XX_HIDRVA_WIDTH 1
 #define XX_LODRVA_LBN 8
 #define XX_LODRVA_WIDTH 1
+#define XX_LPBKD_LBN 3
+#define XX_LPBKD_WIDTH 1
+#define XX_LPBKC_LBN 2
+#define XX_LPBKC_WIDTH 1
+#define XX_LPBKB_LBN 1
+#define XX_LPBKB_WIDTH 1
+#define XX_LPBKA_LBN 0
+#define XX_LPBKA_WIDTH 1
 
 #define XX_TXDRV_CTL_REG_MAC 0x12
 #define XX_DEQD_LBN 28
@@ -656,8 +664,14 @@
 #define XX_DTXA_WIDTH 4
 
 /* XAUI XGXS core status register */
-#define XX_FORCE_SIG_DECODE_FORCED 0xff
 #define XX_CORE_STAT_REG_MAC 0x16
+#define XX_FORCE_SIG_LBN 24
+#define XX_FORCE_SIG_WIDTH 8
+#define XX_FORCE_SIG_DECODE_FORCED 0xff
+#define XX_XGXS_LB_EN_LBN 23
+#define XX_XGXS_LB_EN_WIDTH 1
+#define XX_XGMII_LB_EN_LBN 22
+#define XX_XGMII_LB_EN_WIDTH 1
 #define XX_ALIGN_DONE_LBN 20
 #define XX_ALIGN_DONE_WIDTH 1
 #define XX_SYNC_STAT_LBN 16
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index aa7521b..a74b793 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -32,7 +32,7 @@
 	(FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))
 
 void falcon_xmac_writel(struct efx_nic *efx,
-			efx_dword_t *value, unsigned int mac_reg)
+			 efx_dword_t *value, unsigned int mac_reg)
 {
 	efx_oword_t temp;
 
@@ -69,6 +69,10 @@
 		udelay(10);
 	}
 
+	/* This often fails when DSP is disabled, ignore it */
+	if (sfe4001_phy_flash_cfg != 0)
+		return 0;
+
 	EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
 	return -ETIMEDOUT;
 }
@@ -223,7 +227,7 @@
 	/* The ISR latches, so clear it and re-read */
 	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
 	falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
-	
+
 	if (EFX_DWORD_FIELD(reg, XM_LCLFLT) ||
 	    EFX_DWORD_FIELD(reg, XM_RMTFLT)) {
 		EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
@@ -237,7 +241,7 @@
 {
 	efx_dword_t reg;
 
-	if (FALCON_REV(efx) < FALCON_REV_B0)
+	if ((FALCON_REV(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
 		return;
 
 	/* Flush the ISR */
@@ -284,6 +288,9 @@
 	efx_dword_t reg;
 	int align_done, sync_status, link_ok = 0;
 
+	if (LOOPBACK_INTERNAL(efx))
+		return 1;
+
 	/* Read link status */
 	falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
 
@@ -374,6 +381,61 @@
 	falcon_xmac_writel(efx, &reg, XM_ADR_HI_REG_MAC);
 }
 
+static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
+{
+	efx_dword_t reg;
+	int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0;
+	int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0;
+	int xgmii_loopback =
+		(efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0;
+
+	/* XGXS block is flaky and will need to be reset if moving
+	 * into our out of XGMII, XGXS or XAUI loopbacks. */
+	if (EFX_WORKAROUND_5147(efx)) {
+		int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
+		int reset_xgxs;
+
+		falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
+		old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN);
+		old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN);
+
+		falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
+		old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA);
+
+		/* The PHY driver may have turned XAUI off */
+		reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
+			      (xaui_loopback != old_xaui_loopback) ||
+			      (xgmii_loopback != old_xgmii_loopback));
+		if (reset_xgxs) {
+			falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
+			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
+			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
+			falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
+			udelay(1);
+			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0);
+			EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0);
+			falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
+			udelay(1);
+		}
+	}
+
+	falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
+	EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG,
+			    (xgxs_loopback || xaui_loopback) ?
+			    XX_FORCE_SIG_DECODE_FORCED : 0);
+	EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
+	EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
+	falcon_xmac_writel(efx, &reg, XX_CORE_STAT_REG_MAC);
+
+	falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
+	EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
+	EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
+	EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
+	EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
+	falcon_xmac_writel(efx, &reg, XX_SD_CTL_REG_MAC);
+}
+
+
 /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
  * to come back up. Bash it until it comes back up */
 static int falcon_check_xaui_link_up(struct efx_nic *efx)
@@ -382,7 +444,8 @@
 	tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
 	max_tries = tries;
 
-	if (efx->phy_type == PHY_TYPE_NONE)
+	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
+	    (efx->phy_type == PHY_TYPE_NONE))
 		return 0;
 
 	while (tries) {
@@ -408,8 +471,13 @@
 	falcon_mask_status_intr(efx, 0);
 
 	falcon_deconfigure_mac_wrapper(efx);
+
+	efx->tx_disabled = LOOPBACK_INTERNAL(efx);
 	efx->phy_op->reconfigure(efx);
+
+	falcon_reconfigure_xgxs_core(efx);
 	falcon_reconfigure_xmac_core(efx);
+
 	falcon_reconfigure_mac_wrapper(efx);
 
 	/* Ensure XAUI link is up */
@@ -491,13 +559,15 @@
 		(mac_stats->rx_bytes - mac_stats->rx_good_bytes);
 }
 
-#define EFX_XAUI_RETRAIN_MAX 8
-
 int falcon_check_xmac(struct efx_nic *efx)
 {
 	unsigned xaui_link_ok;
 	int rc;
 
+	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
+	    (efx->phy_type == PHY_TYPE_NONE))
+		return 0;
+
 	falcon_mask_status_intr(efx, 0);
 	xaui_link_ok = falcon_xaui_link_ok(efx);
 
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index dc06bb0..c4f540e 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -44,6 +44,9 @@
 	int status;
 	int phy_id = efx->mii.phy_id;
 
+	if (LOOPBACK_INTERNAL(efx))
+		return 0;
+
 	/* Read MMD STATUS2 to check it is responding. */
 	status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2);
 	if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
@@ -164,6 +167,22 @@
 	int mmd = 0;
 	int good;
 
+	/* If the port is in loopback, then we should only consider a subset
+	 * of mmd's */
+	if (LOOPBACK_INTERNAL(efx))
+		return 1;
+	else if (efx->loopback_mode == LOOPBACK_NETWORK)
+		return 0;
+	else if (efx->loopback_mode == LOOPBACK_PHYXS)
+		mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS |
+			      MDIO_MMDREG_DEVS0_PCS |
+			      MDIO_MMDREG_DEVS0_PMAPMD);
+	else if (efx->loopback_mode == LOOPBACK_PCS)
+		mmd_mask &= ~(MDIO_MMDREG_DEVS0_PCS |
+			      MDIO_MMDREG_DEVS0_PMAPMD);
+	else if (efx->loopback_mode == LOOPBACK_PMAPMD)
+		mmd_mask &= ~MDIO_MMDREG_DEVS0_PMAPMD;
+
 	while (mmd_mask) {
 		if (mmd_mask & 1) {
 			/* Double reads because link state is latched, and a
@@ -182,6 +201,65 @@
 	return ok;
 }
 
+void mdio_clause45_transmit_disable(struct efx_nic *efx)
+{
+	int phy_id = efx->mii.phy_id;
+	int ctrl1, ctrl2;
+
+	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
+					   MDIO_MMDREG_TXDIS);
+	if (efx->tx_disabled)
+		ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
+	else
+		ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
+	if (ctrl1 != ctrl2)
+		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
+				    MDIO_MMDREG_TXDIS, ctrl2);
+}
+
+void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
+{
+	int phy_id = efx->mii.phy_id;
+	int ctrl1, ctrl2;
+
+	/* Handle (with debouncing) PMA/PMD loopback */
+	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
+					   MDIO_MMDREG_CTRL1);
+
+	if (efx->loopback_mode == LOOPBACK_PMAPMD)
+		ctrl2 |= (1 << MDIO_PMAPMD_CTRL1_LBACK_LBN);
+	else
+		ctrl2 &= ~(1 << MDIO_PMAPMD_CTRL1_LBACK_LBN);
+
+	if (ctrl1 != ctrl2)
+		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
+				    MDIO_MMDREG_CTRL1, ctrl2);
+
+	/* Handle (with debouncing) PCS loopback */
+	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
+					   MDIO_MMDREG_CTRL1);
+	if (efx->loopback_mode == LOOPBACK_PCS)
+		ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
+	else
+		ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
+
+	if (ctrl1 != ctrl2)
+		mdio_clause45_write(efx, phy_id, MDIO_MMD_PCS,
+				    MDIO_MMDREG_CTRL1, ctrl2);
+
+	/* Handle (with debouncing) PHYXS network loopback */
+	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
+					   MDIO_MMDREG_CTRL1);
+	if (efx->loopback_mode == LOOPBACK_NETWORK)
+		ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
+	else
+		ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN);
+
+	if (ctrl1 != ctrl2)
+		mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS,
+				    MDIO_MMDREG_CTRL1, ctrl2);
+}
+
 /**
  * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
  * @efx:		Efx NIC
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 2214b6d..cb99f3f 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -44,11 +44,16 @@
 #define MDIO_MMDREG_DEVS1	(6)
 #define MDIO_MMDREG_CTRL2	(7)
 #define MDIO_MMDREG_STAT2	(8)
+#define MDIO_MMDREG_TXDIS	(9)
 
 /* Bits in MMDREG_CTRL1 */
 /* Reset */
 #define MDIO_MMDREG_CTRL1_RESET_LBN	(15)
 #define MDIO_MMDREG_CTRL1_RESET_WIDTH	(1)
+/* Loopback */
+/* Loopback bit for WIS, PCS, PHYSX and DTEXS */
+#define MDIO_MMDREG_CTRL1_LBACK_LBN	(14)
+#define MDIO_MMDREG_CTRL1_LBACK_WIDTH	(1)
 
 /* Bits in MMDREG_STAT1 */
 #define MDIO_MMDREG_STAT1_FAULT_LBN	(7)
@@ -56,6 +61,9 @@
 /* Link state */
 #define MDIO_MMDREG_STAT1_LINK_LBN	(2)
 #define MDIO_MMDREG_STAT1_LINK_WIDTH	(1)
+/* Low power ability */
+#define MDIO_MMDREG_STAT1_LPABLE_LBN	(1)
+#define MDIO_MMDREG_STAT1_LPABLE_WIDTH	(1)
 
 /* Bits in ID reg */
 #define MDIO_ID_REV(_id32)	(_id32 & 0xf)
@@ -76,6 +84,14 @@
 #define MDIO_MMDREG_STAT2_PRESENT_LBN	(14)
 #define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
 
+/* Bits in MMDREG_TXDIS */
+#define MDIO_MMDREG_TXDIS_GLOBAL_LBN    (0)
+#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH  (1)
+
+/* MMD-specific bits, ordered by MMD, then register */
+#define MDIO_PMAPMD_CTRL1_LBACK_LBN	(0)
+#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH	(1)
+
 /* PMA type (4 bits) */
 #define MDIO_PMAPMD_CTRL2_10G_CX4	(0x0)
 #define MDIO_PMAPMD_CTRL2_10G_EW	(0x1)
@@ -95,7 +111,7 @@
 #define MDIO_PMAPMD_CTRL2_10_BT		(0xf)
 #define MDIO_PMAPMD_CTRL2_TYPE_MASK	(0xf)
 
-/* /\* PHY XGXS lane state *\/ */
+/* PHY XGXS lane state */
 #define MDIO_PHYXS_LANE_STATE		(0x18)
 #define MDIO_PHYXS_LANE_ALIGNED_LBN	(12)
 
@@ -217,6 +233,12 @@
 extern int mdio_clause45_links_ok(struct efx_nic *efx,
 				  unsigned int mmd_mask);
 
+/* Generic transmit disable support though PMAPMD */
+extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
+
+/* Generic part of reconfigure: set/clear loopback bits */
+extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
+
 /* Read (some of) the PHY settings over MDIO */
 extern void mdio_clause45_get_settings(struct efx_nic *efx,
 				       struct ethtool_cmd *ecmd);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index c505482..59f261b 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -134,6 +134,8 @@
  *	Set only on the final fragment of a packet; %NULL for all other
  *	fragments.  When this fragment completes, then we can free this
  *	skb.
+ * @tsoh: The associated TSO header structure, or %NULL if this
+ *	buffer is not a TSO header.
  * @dma_addr: DMA address of the fragment.
  * @len: Length of this fragment.
  *	This field is zero when the queue slot is empty.
@@ -144,6 +146,7 @@
  */
 struct efx_tx_buffer {
 	const struct sk_buff *skb;
+	struct efx_tso_header *tsoh;
 	dma_addr_t dma_addr;
 	unsigned short len;
 	unsigned char continuation;
@@ -187,6 +190,13 @@
  *	variable indicates that the queue is full.  This is to
  *	avoid cache-line ping-pong between the xmit path and the
  *	completion path.
+ * @tso_headers_free: A list of TSO headers allocated for this TX queue
+ *	that are not in use, and so available for new TSO sends. The list
+ *	is protected by the TX queue lock.
+ * @tso_bursts: Number of times TSO xmit invoked by kernel
+ * @tso_long_headers: Number of packets with headers too long for standard
+ *	blocks
+ * @tso_packets: Number of packets via the TSO xmit path
  */
 struct efx_tx_queue {
 	/* Members which don't change on the fast path */
@@ -206,6 +216,10 @@
 	unsigned int insert_count ____cacheline_aligned_in_smp;
 	unsigned int write_count;
 	unsigned int old_read_count;
+	struct efx_tso_header *tso_headers_free;
+	unsigned int tso_bursts;
+	unsigned int tso_long_headers;
+	unsigned int tso_packets;
 };
 
 /**
@@ -434,6 +448,9 @@
 	struct efx_blinker blinker;
 };
 
+#define STRING_TABLE_LOOKUP(val, member)	\
+	member ## _names[val]
+
 enum efx_int_mode {
 	/* Be careful if altering to correct macro below */
 	EFX_INT_MODE_MSIX = 0,
@@ -506,6 +523,7 @@
  * @check_hw: Check hardware
  * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset)
  * @mmds: MMD presence mask
+ * @loopbacks: Supported loopback modes mask
  */
 struct efx_phy_operations {
 	int (*init) (struct efx_nic *efx);
@@ -515,6 +533,7 @@
 	int (*check_hw) (struct efx_nic *efx);
 	void (*reset_xaui) (struct efx_nic *efx);
 	int mmds;
+	unsigned loopbacks;
 };
 
 /*
@@ -653,7 +672,6 @@
  * @phy_op: PHY interface
  * @phy_data: PHY private data (including PHY-specific stats)
  * @mii: PHY interface
- * @phy_powered: PHY power state
  * @tx_disabled: PHY transmitter turned off
  * @link_up: Link status
  * @link_options: Link options (MII/GMII format)
@@ -662,6 +680,9 @@
  * @multicast_hash: Multicast hash table
  * @flow_control: Flow control flags - separate RX/TX so can't use link_options
  * @reconfigure_work: work item for dealing with PHY events
+ * @loopback_mode: Loopback status
+ * @loopback_modes: Supported loopback mode bitmask
+ * @loopback_selftest: Offline self-test private state
  *
  * The @priv field of the corresponding &struct net_device points to
  * this.
@@ -721,6 +742,7 @@
 	struct efx_phy_operations *phy_op;
 	void *phy_data;
 	struct mii_if_info mii;
+	unsigned tx_disabled;
 
 	int link_up;
 	unsigned int link_options;
@@ -732,6 +754,10 @@
 	struct work_struct reconfigure_work;
 
 	atomic_t rx_reset;
+	enum efx_loopback_mode loopback_mode;
+	unsigned int loopback_modes;
+
+	void *loopback_selftest;
 };
 
 /**
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 551299b..6706223 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -19,6 +19,7 @@
 #include "rx.h"
 #include "efx.h"
 #include "falcon.h"
+#include "selftest.h"
 #include "workarounds.h"
 
 /* Number of RX descriptors pushed at once. */
@@ -683,6 +684,15 @@
 	struct sk_buff *skb;
 	int lro = efx->net_dev->features & NETIF_F_LRO;
 
+	/* If we're in loopback test, then pass the packet directly to the
+	 * loopback layer, and free the rx_buf here
+	 */
+	if (unlikely(efx->loopback_selftest)) {
+		efx_loopback_rx_packet(efx, rx_buf->data, rx_buf->len);
+		efx_free_rx_buffer(efx, rx_buf);
+		goto done;
+	}
+
 	if (rx_buf->skb) {
 		prefetch(skb_shinfo(rx_buf->skb));
 
@@ -736,7 +746,6 @@
 	/* Update allocation strategy method */
 	channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
 
-	/* fall-thru */
 done:
 	efx->net_dev->last_rx = jiffies;
 }
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
new file mode 100644
index 0000000..cbda159
--- /dev/null
+++ b/drivers/net/sfc/selftest.c
@@ -0,0 +1,717 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2008 Solarflare Communications Inc.
+ *
+ * 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, incorporated herein by reference.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/kernel_stat.h>
+#include <linux/pci.h>
+#include <linux/ethtool.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/udp.h>
+#include <linux/rtnetlink.h>
+#include <asm/io.h>
+#include "net_driver.h"
+#include "ethtool.h"
+#include "efx.h"
+#include "falcon.h"
+#include "selftest.h"
+#include "boards.h"
+#include "workarounds.h"
+#include "mac.h"
+
+/*
+ * Loopback test packet structure
+ *
+ * The self-test should stress every RSS vector, and unfortunately
+ * Falcon only performs RSS on TCP/UDP packets.
+ */
+struct efx_loopback_payload {
+	struct ethhdr header;
+	struct iphdr ip;
+	struct udphdr udp;
+	__be16 iteration;
+	const char msg[64];
+} __attribute__ ((packed));
+
+/* Loopback test source MAC address */
+static const unsigned char payload_source[ETH_ALEN] = {
+	0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b,
+};
+
+static const char *payload_msg =
+	"Hello world! This is an Efx loopback test in progress!";
+
+/**
+ * efx_selftest_state - persistent state during a selftest
+ * @flush:		Drop all packets in efx_loopback_rx_packet
+ * @packet_count:	Number of packets being used in this test
+ * @skbs:		An array of skbs transmitted
+ * @rx_good:		RX good packet count
+ * @rx_bad:		RX bad packet count
+ * @payload:		Payload used in tests
+ */
+struct efx_selftest_state {
+	int flush;
+	int packet_count;
+	struct sk_buff **skbs;
+	atomic_t rx_good;
+	atomic_t rx_bad;
+	struct efx_loopback_payload payload;
+};
+
+/**************************************************************************
+ *
+ * Configurable values
+ *
+ **************************************************************************/
+
+/* Level of loopback testing
+ *
+ * The maximum packet burst length is 16**(n-1), i.e.
+ *
+ * - Level 0 : no packets
+ * - Level 1 : 1 packet
+ * - Level 2 : 17 packets (1 * 1 packet, 1 * 16 packets)
+ * - Level 3 : 273 packets (1 * 1 packet, 1 * 16 packet, 1 * 256 packets)
+ *
+ */
+static unsigned int loopback_test_level = 3;
+
+/**************************************************************************
+ *
+ * Interrupt and event queue testing
+ *
+ **************************************************************************/
+
+/* Test generation and receipt of interrupts */
+static int efx_test_interrupts(struct efx_nic *efx,
+			       struct efx_self_tests *tests)
+{
+	struct efx_channel *channel;
+
+	EFX_LOG(efx, "testing interrupts\n");
+	tests->interrupt = -1;
+
+	/* Reset interrupt flag */
+	efx->last_irq_cpu = -1;
+	smp_wmb();
+
+	/* ACK each interrupting event queue. Receiving an interrupt due to
+	 * traffic before a test event is raised is considered a pass */
+	efx_for_each_channel_with_interrupt(channel, efx) {
+		if (channel->work_pending)
+			efx_process_channel_now(channel);
+		if (efx->last_irq_cpu >= 0)
+			goto success;
+	}
+
+	falcon_generate_interrupt(efx);
+
+	/* Wait for arrival of test interrupt. */
+	EFX_LOG(efx, "waiting for test interrupt\n");
+	schedule_timeout_uninterruptible(HZ / 10);
+	if (efx->last_irq_cpu >= 0)
+		goto success;
+
+	EFX_ERR(efx, "timed out waiting for interrupt\n");
+	return -ETIMEDOUT;
+
+ success:
+	EFX_LOG(efx, "test interrupt (mode %d) seen on CPU%d\n",
+		efx->interrupt_mode, efx->last_irq_cpu);
+	tests->interrupt = 1;
+	return 0;
+}
+
+/* Test generation and receipt of non-interrupting events */
+static int efx_test_eventq(struct efx_channel *channel,
+			   struct efx_self_tests *tests)
+{
+	unsigned int magic;
+
+	/* Channel specific code, limited to 20 bits */
+	magic = (0x00010150 + channel->channel);
+	EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n",
+		channel->channel, magic);
+
+	tests->eventq_dma[channel->channel] = -1;
+	tests->eventq_int[channel->channel] = 1;	/* fake pass */
+	tests->eventq_poll[channel->channel] = 1;	/* fake pass */
+
+	/* Reset flag and zero magic word */
+	channel->efx->last_irq_cpu = -1;
+	channel->eventq_magic = 0;
+	smp_wmb();
+
+	falcon_generate_test_event(channel, magic);
+	udelay(1);
+
+	efx_process_channel_now(channel);
+	if (channel->eventq_magic != magic) {
+		EFX_ERR(channel->efx, "channel %d  failed to see test event\n",
+			channel->channel);
+		return -ETIMEDOUT;
+	} else {
+		tests->eventq_dma[channel->channel] = 1;
+	}
+
+	return 0;
+}
+
+/* Test generation and receipt of interrupting events */
+static int efx_test_eventq_irq(struct efx_channel *channel,
+			       struct efx_self_tests *tests)
+{
+	unsigned int magic, count;
+
+	/* Channel specific code, limited to 20 bits */
+	magic = (0x00010150 + channel->channel);
+	EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n",
+		channel->channel, magic);
+
+	tests->eventq_dma[channel->channel] = -1;
+	tests->eventq_int[channel->channel] = -1;
+	tests->eventq_poll[channel->channel] = -1;
+
+	/* Reset flag and zero magic word */
+	channel->efx->last_irq_cpu = -1;
+	channel->eventq_magic = 0;
+	smp_wmb();
+
+	falcon_generate_test_event(channel, magic);
+
+	/* Wait for arrival of interrupt */
+	count = 0;
+	do {
+		schedule_timeout_uninterruptible(HZ / 100);
+
+		if (channel->work_pending)
+			efx_process_channel_now(channel);
+
+		if (channel->eventq_magic == magic)
+			goto eventq_ok;
+	} while (++count < 2);
+
+	EFX_ERR(channel->efx, "channel %d timed out waiting for event queue\n",
+		channel->channel);
+
+	/* See if interrupt arrived */
+	if (channel->efx->last_irq_cpu >= 0) {
+		EFX_ERR(channel->efx, "channel %d saw interrupt on CPU%d "
+			"during event queue test\n", channel->channel,
+			raw_smp_processor_id());
+		tests->eventq_int[channel->channel] = 1;
+	}
+
+	/* Check to see if event was received even if interrupt wasn't */
+	efx_process_channel_now(channel);
+	if (channel->eventq_magic == magic) {
+		EFX_ERR(channel->efx, "channel %d event was generated, but "
+			"failed to trigger an interrupt\n", channel->channel);
+		tests->eventq_dma[channel->channel] = 1;
+	}
+
+	return -ETIMEDOUT;
+ eventq_ok:
+	EFX_LOG(channel->efx, "channel %d event queue passed\n",
+		channel->channel);
+	tests->eventq_dma[channel->channel] = 1;
+	tests->eventq_int[channel->channel] = 1;
+	tests->eventq_poll[channel->channel] = 1;
+	return 0;
+}
+
+/**************************************************************************
+ *
+ * PHY testing
+ *
+ **************************************************************************/
+
+/* Check PHY presence by reading the PHY ID registers */
+static int efx_test_phy(struct efx_nic *efx,
+			struct efx_self_tests *tests)
+{
+	u16 physid1, physid2;
+	struct mii_if_info *mii = &efx->mii;
+	struct net_device *net_dev = efx->net_dev;
+
+	if (efx->phy_type == PHY_TYPE_NONE)
+		return 0;
+
+	EFX_LOG(efx, "testing PHY presence\n");
+	tests->phy_ok = -1;
+
+	physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
+	physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
+
+	if ((physid1 != 0x0000) && (physid1 != 0xffff) &&
+	    (physid2 != 0x0000) && (physid2 != 0xffff)) {
+		EFX_LOG(efx, "found MII PHY %d ID 0x%x:%x\n",
+			mii->phy_id, physid1, physid2);
+		tests->phy_ok = 1;
+		return 0;
+	}
+
+	EFX_ERR(efx, "no MII PHY present with ID %d\n", mii->phy_id);
+	return -ENODEV;
+}
+
+/**************************************************************************
+ *
+ * Loopback testing
+ * NB Only one loopback test can be executing concurrently.
+ *
+ **************************************************************************/
+
+/* Loopback test RX callback
+ * This is called for each received packet during loopback testing.
+ */
+void efx_loopback_rx_packet(struct efx_nic *efx,
+			    const char *buf_ptr, int pkt_len)
+{
+	struct efx_selftest_state *state = efx->loopback_selftest;
+	struct efx_loopback_payload *received;
+	struct efx_loopback_payload *payload;
+
+	BUG_ON(!buf_ptr);
+
+	/* If we are just flushing, then drop the packet */
+	if ((state == NULL) || state->flush)
+		return;
+
+	payload = &state->payload;
+	
+	received = (struct efx_loopback_payload *)(char *) buf_ptr;
+	received->ip.saddr = payload->ip.saddr;
+	received->ip.check = payload->ip.check;
+	
+	/* Check that header exists */
+	if (pkt_len < sizeof(received->header)) {
+		EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback "
+			"test\n", pkt_len, LOOPBACK_MODE(efx));
+		goto err;
+	}
+
+	/* Check that the ethernet header exists */
+	if (memcmp(&received->header, &payload->header, ETH_HLEN) != 0) {
+		EFX_ERR(efx, "saw non-loopback RX packet in %s loopback test\n",
+			LOOPBACK_MODE(efx));
+		goto err;
+	}
+
+	/* Check packet length */
+	if (pkt_len != sizeof(*payload)) {
+		EFX_ERR(efx, "saw incorrect RX packet length %d (wanted %d) in "
+			"%s loopback test\n", pkt_len, (int)sizeof(*payload),
+			LOOPBACK_MODE(efx));
+		goto err;
+	}
+
+	/* Check that IP header matches */
+	if (memcmp(&received->ip, &payload->ip, sizeof(payload->ip)) != 0) {
+		EFX_ERR(efx, "saw corrupted IP header in %s loopback test\n",
+			LOOPBACK_MODE(efx));
+		goto err;
+	}
+
+	/* Check that msg and padding matches */
+	if (memcmp(&received->msg, &payload->msg, sizeof(received->msg)) != 0) {
+		EFX_ERR(efx, "saw corrupted RX packet in %s loopback test\n",
+			LOOPBACK_MODE(efx));
+		goto err;
+	}
+
+	/* Check that iteration matches */
+	if (received->iteration != payload->iteration) {
+		EFX_ERR(efx, "saw RX packet from iteration %d (wanted %d) in "
+			"%s loopback test\n", ntohs(received->iteration),
+			ntohs(payload->iteration), LOOPBACK_MODE(efx));
+		goto err;
+	}
+
+	/* Increase correct RX count */
+	EFX_TRACE(efx, "got loopback RX in %s loopback test\n",
+		  LOOPBACK_MODE(efx));
+
+	atomic_inc(&state->rx_good);
+	return;
+
+ err:
+#ifdef EFX_ENABLE_DEBUG
+	if (atomic_read(&state->rx_bad) == 0) {
+		EFX_ERR(efx, "received packet:\n");
+		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
+			       buf_ptr, pkt_len, 0);
+		EFX_ERR(efx, "expected packet:\n");
+		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
+			       &state->payload, sizeof(state->payload), 0);
+	}
+#endif
+	atomic_inc(&state->rx_bad);
+}
+
+/* Initialise an efx_selftest_state for a new iteration */
+static void efx_iterate_state(struct efx_nic *efx)
+{
+	struct efx_selftest_state *state = efx->loopback_selftest;
+	struct net_device *net_dev = efx->net_dev;
+	struct efx_loopback_payload *payload = &state->payload;
+
+	/* Initialise the layerII header */
+	memcpy(&payload->header.h_dest, net_dev->dev_addr, ETH_ALEN);
+	memcpy(&payload->header.h_source, &payload_source, ETH_ALEN);
+	payload->header.h_proto = htons(ETH_P_IP);
+
+	/* saddr set later and used as incrementing count */
+	payload->ip.daddr = htonl(INADDR_LOOPBACK);
+	payload->ip.ihl = 5;
+	payload->ip.check = htons(0xdead);
+	payload->ip.tot_len = htons(sizeof(*payload) - sizeof(struct ethhdr));
+	payload->ip.version = IPVERSION;
+	payload->ip.protocol = IPPROTO_UDP;
+
+	/* Initialise udp header */
+	payload->udp.source = 0;
+	payload->udp.len = htons(sizeof(*payload) - sizeof(struct ethhdr) -
+				 sizeof(struct iphdr));
+	payload->udp.check = 0;	/* checksum ignored */
+
+	/* Fill out payload */
+	payload->iteration = htons(ntohs(payload->iteration) + 1);
+	memcpy(&payload->msg, payload_msg, sizeof(payload_msg));
+
+	/* Fill out remaining state members */
+	atomic_set(&state->rx_good, 0);
+	atomic_set(&state->rx_bad, 0);
+	smp_wmb();
+}
+
+static int efx_tx_loopback(struct efx_tx_queue *tx_queue)
+{
+	struct efx_nic *efx = tx_queue->efx;
+	struct efx_selftest_state *state = efx->loopback_selftest;
+	struct efx_loopback_payload *payload;
+	struct sk_buff *skb;
+	int i, rc;
+
+	/* Transmit N copies of buffer */
+	for (i = 0; i < state->packet_count; i++) {
+		/* Allocate an skb, holding an extra reference for 
+		 * transmit completion counting */
+		skb = alloc_skb(sizeof(state->payload), GFP_KERNEL);
+		if (!skb)
+			return -ENOMEM;
+		state->skbs[i] = skb;
+		skb_get(skb);
+
+		/* Copy the payload in, incrementing the source address to
+		 * exercise the rss vectors */
+		payload = ((struct efx_loopback_payload *)
+			   skb_put(skb, sizeof(state->payload)));
+		memcpy(payload, &state->payload, sizeof(state->payload));
+		payload->ip.saddr = htonl(INADDR_LOOPBACK | (i << 2));
+
+		/* Ensure everything we've written is visible to the
+		 * interrupt handler. */
+		smp_wmb();
+
+		if (NET_DEV_REGISTERED(efx))
+			netif_tx_lock_bh(efx->net_dev);
+		rc = efx_xmit(efx, tx_queue, skb);
+		if (NET_DEV_REGISTERED(efx))
+			netif_tx_unlock_bh(efx->net_dev);
+
+		if (rc != NETDEV_TX_OK) {
+			EFX_ERR(efx, "TX queue %d could not transmit packet %d "
+				"of %d in %s loopback test\n", tx_queue->queue,
+				i + 1, state->packet_count, LOOPBACK_MODE(efx));
+
+			/* Defer cleaning up the other skbs for the caller */
+			kfree_skb(skb);
+			return -EPIPE;
+		}
+	}
+
+	return 0;
+}
+
+static int efx_rx_loopback(struct efx_tx_queue *tx_queue,
+			   struct efx_loopback_self_tests *lb_tests)
+{
+	struct efx_nic *efx = tx_queue->efx;
+	struct efx_selftest_state *state = efx->loopback_selftest;
+	struct sk_buff *skb;
+	int tx_done = 0, rx_good, rx_bad;
+	int i, rc = 0;
+
+	if (NET_DEV_REGISTERED(efx))
+		netif_tx_lock_bh(efx->net_dev);
+
+	/* Count the number of tx completions, and decrement the refcnt. Any
+	 * skbs not already completed will be free'd when the queue is flushed */
+	for (i=0; i < state->packet_count; i++) {
+		skb = state->skbs[i];
+		if (skb && !skb_shared(skb))
+			++tx_done;
+		dev_kfree_skb_any(skb);
+	}
+
+	if (NET_DEV_REGISTERED(efx))
+		netif_tx_unlock_bh(efx->net_dev);
+
+	/* Check TX completion and received packet counts */
+	rx_good = atomic_read(&state->rx_good);
+	rx_bad = atomic_read(&state->rx_bad);
+	if (tx_done != state->packet_count) {
+		/* Don't free the skbs; they will be picked up on TX
+		 * overflow or channel teardown.
+		 */
+		EFX_ERR(efx, "TX queue %d saw only %d out of an expected %d "
+			"TX completion events in %s loopback test\n",
+			tx_queue->queue, tx_done, state->packet_count,
+			LOOPBACK_MODE(efx));
+		rc = -ETIMEDOUT;
+		/* Allow to fall through so we see the RX errors as well */
+	}
+
+	/* We may always be up to a flush away from our desired packet total */
+	if (rx_good != state->packet_count) {
+		EFX_LOG(efx, "TX queue %d saw only %d out of an expected %d "
+			"received packets in %s loopback test\n",
+			tx_queue->queue, rx_good, state->packet_count,
+			LOOPBACK_MODE(efx));
+		rc = -ETIMEDOUT;
+		/* Fall through */
+	}
+
+	/* Update loopback test structure */
+	lb_tests->tx_sent[tx_queue->queue] += state->packet_count;
+	lb_tests->tx_done[tx_queue->queue] += tx_done;
+	lb_tests->rx_good += rx_good;
+	lb_tests->rx_bad += rx_bad;
+
+	return rc;
+}
+
+static int
+efx_test_loopback(struct efx_tx_queue *tx_queue,
+		  struct efx_loopback_self_tests *lb_tests)
+{
+	struct efx_nic *efx = tx_queue->efx;
+	struct efx_selftest_state *state = efx->loopback_selftest;
+	struct efx_channel *channel;
+	int i, rc = 0;
+
+	for (i = 0; i < loopback_test_level; i++) {
+		/* Determine how many packets to send */
+		state->packet_count = (efx->type->txd_ring_mask + 1) / 3;
+		state->packet_count = min(1 << (i << 2), state->packet_count);
+		state->skbs = kzalloc(sizeof(state->skbs[0]) *
+				      state->packet_count, GFP_KERNEL);
+		state->flush = 0;
+
+		EFX_LOG(efx, "TX queue %d testing %s loopback with %d "
+			"packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
+			state->packet_count);
+
+		efx_iterate_state(efx);
+		rc = efx_tx_loopback(tx_queue);
+		
+		/* NAPI polling is not enabled, so process channels synchronously */
+		schedule_timeout_uninterruptible(HZ / 50);
+		efx_for_each_channel_with_interrupt(channel, efx) {
+			if (channel->work_pending)
+				efx_process_channel_now(channel);
+		}
+
+		rc |= efx_rx_loopback(tx_queue, lb_tests);
+		kfree(state->skbs);
+
+		if (rc) {
+			/* Wait a while to ensure there are no packets
+			 * floating around after a failure. */
+			schedule_timeout_uninterruptible(HZ / 10);
+			return rc;
+		}
+	}
+
+	EFX_LOG(efx, "TX queue %d passed %s loopback test with a burst length "
+		"of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
+		state->packet_count);
+
+	return rc;
+}
+
+static int efx_test_loopbacks(struct efx_nic *efx,
+			      struct efx_self_tests *tests,
+			      unsigned int loopback_modes)
+{
+	struct efx_selftest_state *state = efx->loopback_selftest;
+	struct ethtool_cmd ecmd, ecmd_loopback;
+	struct efx_tx_queue *tx_queue;
+	enum efx_loopback_mode old_mode, mode;
+	int count, rc = 0, link_up;
+	
+	rc = efx_ethtool_get_settings(efx->net_dev, &ecmd);
+	if (rc) {
+		EFX_ERR(efx, "could not get GMII settings\n");
+		return rc;
+	}
+	old_mode = efx->loopback_mode;
+
+	/* Disable autonegotiation for the purposes of loopback */
+	memcpy(&ecmd_loopback, &ecmd, sizeof(ecmd_loopback));
+	if (ecmd_loopback.autoneg == AUTONEG_ENABLE) {
+		ecmd_loopback.autoneg = AUTONEG_DISABLE;
+		ecmd_loopback.duplex = DUPLEX_FULL;
+		ecmd_loopback.speed = SPEED_10000;
+	}
+
+	rc = efx_ethtool_set_settings(efx->net_dev, &ecmd_loopback);
+	if (rc) {
+		EFX_ERR(efx, "could not disable autonegotiation\n");
+		goto out;
+	}
+	tests->loopback_speed = ecmd_loopback.speed;
+	tests->loopback_full_duplex = ecmd_loopback.duplex;
+
+	/* Test all supported loopback modes */
+	for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) {
+		if (!(loopback_modes & (1 << mode)))
+			continue;
+
+		/* Move the port into the specified loopback mode. */
+		state->flush = 1;
+		efx->loopback_mode = mode;
+		efx_reconfigure_port(efx);
+
+		/* Wait for the PHY to signal the link is up */
+		count = 0;
+		do {
+			struct efx_channel *channel = &efx->channel[0];
+
+			falcon_check_xmac(efx);
+			schedule_timeout_uninterruptible(HZ / 10);
+			if (channel->work_pending)
+				efx_process_channel_now(channel);
+			/* Wait for PHY events to be processed */
+			flush_workqueue(efx->workqueue);
+			rmb();
+
+			/* efx->link_up can be 1 even if the XAUI link is down,
+			 * (bug5762). Usually, it's not worth bothering with the
+			 * difference, but for selftests, we need that extra
+			 * guarantee that the link is really, really, up.
+			 */
+			link_up = efx->link_up;
+			if (!falcon_xaui_link_ok(efx))
+				link_up = 0;
+
+		} while ((++count < 20) && !link_up);
+
+		/* The link should now be up. If it isn't, there is no point
+		 * in attempting a loopback test */
+		if (!link_up) {
+			EFX_ERR(efx, "loopback %s never came up\n",
+				LOOPBACK_MODE(efx));
+			rc = -EIO;
+			goto out;
+		}
+
+		EFX_LOG(efx, "link came up in %s loopback in %d iterations\n",
+			LOOPBACK_MODE(efx), count);
+
+		/* Test every TX queue */
+		efx_for_each_tx_queue(tx_queue, efx) {
+			rc |= efx_test_loopback(tx_queue,
+						&tests->loopback[mode]);
+			if (rc)
+				goto out;
+		}
+	}
+
+ out:
+	/* Take out of loopback and restore PHY settings */
+	state->flush = 1;
+	efx->loopback_mode = old_mode;
+	efx_ethtool_set_settings(efx->net_dev, &ecmd);
+
+	return rc;
+}
+
+/**************************************************************************
+ *
+ * Entry points
+ *
+ *************************************************************************/
+
+/* Online (i.e. non-disruptive) testing
+ * This checks interrupt generation, event delivery and PHY presence. */
+int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests)
+{
+	struct efx_channel *channel;
+	int rc = 0;
+
+	EFX_LOG(efx, "performing online self-tests\n");
+
+	rc |= efx_test_interrupts(efx, tests);
+	efx_for_each_channel(channel, efx) {
+		if (channel->has_interrupt)
+			rc |= efx_test_eventq_irq(channel, tests);
+		else
+			rc |= efx_test_eventq(channel, tests);
+	}
+	rc |= efx_test_phy(efx, tests);
+
+	if (rc)
+		EFX_ERR(efx, "failed online self-tests\n");
+
+	return rc;
+}
+
+/* Offline (i.e. disruptive) testing
+ * This checks MAC and PHY loopback on the specified port. */
+int efx_offline_test(struct efx_nic *efx,
+		     struct efx_self_tests *tests, unsigned int loopback_modes)
+{
+	struct efx_selftest_state *state;
+	int rc = 0;
+
+	EFX_LOG(efx, "performing offline self-tests\n");
+
+	/* Create a selftest_state structure to hold state for the test */
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (state == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Set the port loopback_selftest member. From this point on
+	 * all received packets will be dropped. Mark the state as
+	 * "flushing" so all inflight packets are dropped */
+	BUG_ON(efx->loopback_selftest);
+	state->flush = 1;
+	efx->loopback_selftest = (void *)state;
+
+	rc = efx_test_loopbacks(efx, tests, loopback_modes);
+
+	efx->loopback_selftest = NULL;
+	wmb();
+	kfree(state);
+
+ out:
+	if (rc)
+		EFX_ERR(efx, "failed offline self-tests\n");
+
+	return rc;
+}
+
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
new file mode 100644
index 0000000..f6999c2
--- /dev/null
+++ b/drivers/net/sfc/selftest.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2008 Solarflare Communications Inc.
+ *
+ * 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, incorporated herein by reference.
+ */
+
+#ifndef EFX_SELFTEST_H
+#define EFX_SELFTEST_H
+
+#include "net_driver.h"
+
+/*
+ * Self tests
+ */
+
+struct efx_loopback_self_tests {
+	int tx_sent[EFX_MAX_TX_QUEUES];
+	int tx_done[EFX_MAX_TX_QUEUES];
+	int rx_good;
+	int rx_bad;
+};
+
+/* Efx self test results
+ * For fields which are not counters, 1 indicates success and -1
+ * indicates failure.
+ */
+struct efx_self_tests {
+	int interrupt;
+	int eventq_dma[EFX_MAX_CHANNELS];
+	int eventq_int[EFX_MAX_CHANNELS];
+	int eventq_poll[EFX_MAX_CHANNELS];
+	int phy_ok;
+	int loopback_speed;
+	int loopback_full_duplex;
+	struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX];
+};
+
+extern void efx_loopback_rx_packet(struct efx_nic *efx,
+				   const char *buf_ptr, int pkt_len);
+extern int efx_online_test(struct efx_nic *efx,
+			   struct efx_self_tests *tests);
+extern int efx_offline_test(struct efx_nic *efx,
+			    struct efx_self_tests *tests,
+			    unsigned int loopback_modes);
+
+#endif /* EFX_SELFTEST_H */
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 11fa9fb..725d1a5 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -130,6 +130,15 @@
 	(void) efx_i2c_read(i2c, MAX6647, RSL, &in, 1);
 }
 
+/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected
+ * to the FLASH_CFG_1 input on the DSP.  We must keep it high at power-
+ * up to allow writing the flash (done through MDIO from userland).
+ */
+unsigned int sfe4001_phy_flash_cfg;
+module_param_named(phy_flash_cfg, sfe4001_phy_flash_cfg, uint, 0444);
+MODULE_PARM_DESC(phy_flash_cfg,
+		 "Force PHY to enter flash configuration mode");
+
 /* This board uses an I2C expander to provider power to the PHY, which needs to
  * be turned on before the PHY can be used.
  * Context: Process context, rtnl lock held
@@ -203,6 +212,8 @@
 		out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
 			       (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
 			       (1 << P0_X_TRST_LBN));
+		if (sfe4001_phy_flash_cfg)
+			out |= 1 << P0_EN_3V3X_LBN;
 
 		rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1);
 		if (rc)
@@ -226,6 +237,9 @@
 		if (in & (1 << P1_AFE_PWD_LBN))
 			goto done;
 
+		/* DSP doesn't look powered in flash config mode */
+		if (sfe4001_phy_flash_cfg)
+			goto done;
 	} while (++count < 20);
 
 	EFX_INFO(efx, "timed out waiting for power\n");
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index a2e9f79..b1cd6de 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -24,6 +24,11 @@
 				 MDIO_MMDREG_DEVS0_PCS    | \
 				 MDIO_MMDREG_DEVS0_PHYXS)
 
+#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) |	\
+			     (1 << LOOPBACK_PCS) |	\
+			     (1 << LOOPBACK_PMAPMD) |	\
+			     (1 << LOOPBACK_NETWORK))
+
 /* We complain if we fail to see the link partner as 10G capable this many
  * times in a row (must be > 1 as sampling the autoneg. registers is racy)
  */
@@ -72,6 +77,10 @@
 #define PMA_PMD_BIST_RXD_LBN	(1)
 #define PMA_PMD_BIST_AFE_LBN	(0)
 
+/* Special Software reset register */
+#define PMA_PMD_EXT_CTRL_REG 49152
+#define PMA_PMD_EXT_SSR_LBN 15
+
 #define BIST_MAX_DELAY	(1000)
 #define BIST_POLL_DELAY	(10)
 
@@ -86,6 +95,11 @@
 #define	PCS_TEST_SELECT_REG 0xd807	/* PRM 10.5.8 */
 #define	CLK312_EN_LBN 3
 
+/* PHYXS registers */
+#define PHYXS_TEST1         (49162)
+#define LOOPBACK_NEAR_LBN   (8)
+#define LOOPBACK_NEAR_WIDTH (1)
+
 /* Boot status register */
 #define PCS_BOOT_STATUS_REG	(0xd000)
 #define PCS_BOOT_FATAL_ERR_LBN	(0)
@@ -106,7 +120,9 @@
 
 struct tenxpress_phy_data {
 	enum tenxpress_state state;
+	enum efx_loopback_mode loopback_mode;
 	atomic_t bad_crc_count;
+	int tx_disabled;
 	int bad_lp_tries;
 };
 
@@ -199,10 +215,12 @@
 
 	tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL);
 
-	rc = mdio_clause45_wait_reset_mmds(efx,
-					   TENXPRESS_REQUIRED_DEVS);
-	if (rc < 0)
-		goto fail;
+	if (!sfe4001_phy_flash_cfg) {
+		rc = mdio_clause45_wait_reset_mmds(efx,
+						   TENXPRESS_REQUIRED_DEVS);
+		if (rc < 0)
+			goto fail;
+	}
 
 	rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
 	if (rc < 0)
@@ -225,6 +243,35 @@
 	return rc;
 }
 
+static int tenxpress_special_reset(struct efx_nic *efx)
+{
+	int rc, reg;
+
+	EFX_TRACE(efx, "%s\n", __func__);
+
+	/* Initiate reset */
+	reg = mdio_clause45_read(efx, efx->mii.phy_id,
+				 MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG);
+	reg |= (1 << PMA_PMD_EXT_SSR_LBN);
+	mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
+			    PMA_PMD_EXT_CTRL_REG, reg);
+
+	msleep(200);
+
+	/* Wait for the blocks to come out of reset */
+	rc = mdio_clause45_wait_reset_mmds(efx,
+					   TENXPRESS_REQUIRED_DEVS);
+	if (rc < 0)
+		return rc;
+
+	/* Try and reconfigure the device */
+	rc = tenxpress_init(efx);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
 static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp)
 {
 	struct tenxpress_phy_data *pd = efx->phy_data;
@@ -299,11 +346,46 @@
 	return ok;
 }
 
+static void tenxpress_phyxs_loopback(struct efx_nic *efx)
+{
+	int phy_id = efx->mii.phy_id;
+	int ctrl1, ctrl2;
+
+	ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
+					   PHYXS_TEST1);
+	if (efx->loopback_mode == LOOPBACK_PHYXS)
+		ctrl2 |= (1 << LOOPBACK_NEAR_LBN);
+	else
+		ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN);
+	if (ctrl1 != ctrl2)
+		mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS,
+				    PHYXS_TEST1, ctrl2);
+}
+
 static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 {
+	struct tenxpress_phy_data *phy_data = efx->phy_data;
+	int loop_change = LOOPBACK_OUT_OF(phy_data, efx,
+					  TENXPRESS_LOOPBACKS);
+
 	if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL))
 		return;
 
+	/* When coming out of transmit disable, coming out of low power
+	 * mode, or moving out of any PHY internal loopback mode,
+	 * perform a special software reset */
+	if ((phy_data->tx_disabled && !efx->tx_disabled) ||
+	    loop_change) {
+		(void) tenxpress_special_reset(efx);
+		falcon_reset_xaui(efx);
+	}
+
+	mdio_clause45_transmit_disable(efx);
+	mdio_clause45_phy_reconfigure(efx);
+	tenxpress_phyxs_loopback(efx);
+
+	phy_data->tx_disabled = efx->tx_disabled;
+	phy_data->loopback_mode = efx->loopback_mode;
 	efx->link_up = tenxpress_link_ok(efx, 0);
 	efx->link_options = GM_LPA_10000FULL;
 }
@@ -431,4 +513,5 @@
 	.clear_interrupt  = tenxpress_phy_clear_interrupt,
 	.reset_xaui       = tenxpress_reset_xaui,
 	.mmds             = TENXPRESS_REQUIRED_DEVS,
+	.loopbacks        = TENXPRESS_LOOPBACKS,
 };
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index fbb866b..9b436f5 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -82,6 +82,46 @@
 	}
 }
 
+/**
+ * struct efx_tso_header - a DMA mapped buffer for packet headers
+ * @next: Linked list of free ones.
+ *	The list is protected by the TX queue lock.
+ * @dma_unmap_len: Length to unmap for an oversize buffer, or 0.
+ * @dma_addr: The DMA address of the header below.
+ *
+ * This controls the memory used for a TSO header.  Use TSOH_DATA()
+ * to find the packet header data.  Use TSOH_SIZE() to calculate the
+ * total size required for a given packet header length.  TSO headers
+ * in the free list are exactly %TSOH_STD_SIZE bytes in size.
+ */
+struct efx_tso_header {
+	union {
+		struct efx_tso_header *next;
+		size_t unmap_len;
+	};
+	dma_addr_t dma_addr;
+};
+
+static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
+			       const struct sk_buff *skb);
+static void efx_fini_tso(struct efx_tx_queue *tx_queue);
+static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue,
+			       struct efx_tso_header *tsoh);
+
+static inline void efx_tsoh_free(struct efx_tx_queue *tx_queue,
+				 struct efx_tx_buffer *buffer)
+{
+	if (buffer->tsoh) {
+		if (likely(!buffer->tsoh->unmap_len)) {
+			buffer->tsoh->next = tx_queue->tso_headers_free;
+			tx_queue->tso_headers_free = buffer->tsoh;
+		} else {
+			efx_tsoh_heap_free(tx_queue, buffer->tsoh);
+		}
+		buffer->tsoh = NULL;
+	}
+}
+
 
 /*
  * Add a socket buffer to a TX queue
@@ -114,6 +154,9 @@
 
 	EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
 
+	if (skb_shinfo((struct sk_buff *)skb)->gso_size)
+		return efx_enqueue_skb_tso(tx_queue, skb);
+
 	/* Get size of the initial fragment */
 	len = skb_headlen(skb);
 
@@ -166,6 +209,8 @@
 			insert_ptr = (tx_queue->insert_count &
 				      efx->type->txd_ring_mask);
 			buffer = &tx_queue->buffer[insert_ptr];
+			efx_tsoh_free(tx_queue, buffer);
+			EFX_BUG_ON_PARANOID(buffer->tsoh);
 			EFX_BUG_ON_PARANOID(buffer->skb);
 			EFX_BUG_ON_PARANOID(buffer->len);
 			EFX_BUG_ON_PARANOID(buffer->continuation != 1);
@@ -432,6 +477,9 @@
 
 	efx_release_tx_buffers(tx_queue);
 
+	/* Free up TSO header cache */
+	efx_fini_tso(tx_queue);
+
 	/* Release queue's stop on port, if any */
 	if (tx_queue->stopped) {
 		tx_queue->stopped = 0;
@@ -450,3 +498,619 @@
 }
 
 
+/* Efx TCP segmentation acceleration.
+ *
+ * Why?  Because by doing it here in the driver we can go significantly
+ * faster than the GSO.
+ *
+ * Requires TX checksum offload support.
+ */
+
+/* Number of bytes inserted at the start of a TSO header buffer,
+ * similar to NET_IP_ALIGN.
+ */
+#if defined(__i386__) || defined(__x86_64__)
+#define TSOH_OFFSET	0
+#else
+#define TSOH_OFFSET	NET_IP_ALIGN
+#endif
+
+#define TSOH_BUFFER(tsoh)	((u8 *)(tsoh + 1) + TSOH_OFFSET)
+
+/* Total size of struct efx_tso_header, buffer and padding */
+#define TSOH_SIZE(hdr_len)					\
+	(sizeof(struct efx_tso_header) + TSOH_OFFSET + hdr_len)
+
+/* Size of blocks on free list.  Larger blocks must be allocated from
+ * the heap.
+ */
+#define TSOH_STD_SIZE		128
+
+#define PTR_DIFF(p1, p2)  ((u8 *)(p1) - (u8 *)(p2))
+#define ETH_HDR_LEN(skb)  (skb_network_header(skb) - (skb)->data)
+#define SKB_TCP_OFF(skb)  PTR_DIFF(tcp_hdr(skb), (skb)->data)
+#define SKB_IPV4_OFF(skb) PTR_DIFF(ip_hdr(skb), (skb)->data)
+
+/**
+ * struct tso_state - TSO state for an SKB
+ * @remaining_len: Bytes of data we've yet to segment
+ * @seqnum: Current sequence number
+ * @packet_space: Remaining space in current packet
+ * @ifc: Input fragment cursor.
+ *	Where we are in the current fragment of the incoming SKB.  These
+ *	values get updated in place when we split a fragment over
+ *	multiple packets.
+ * @p: Parameters.
+ *	These values are set once at the start of the TSO send and do
+ *	not get changed as the routine progresses.
+ *
+ * The state used during segmentation.  It is put into this data structure
+ * just to make it easy to pass into inline functions.
+ */
+struct tso_state {
+	unsigned remaining_len;
+	unsigned seqnum;
+	unsigned packet_space;
+
+	struct {
+		/* DMA address of current position */
+		dma_addr_t dma_addr;
+		/* Remaining length */
+		unsigned int len;
+		/* DMA address and length of the whole fragment */
+		unsigned int unmap_len;
+		dma_addr_t unmap_addr;
+		struct page *page;
+		unsigned page_off;
+	} ifc;
+
+	struct {
+		/* The number of bytes of header */
+		unsigned int header_length;
+
+		/* The number of bytes to put in each outgoing segment. */
+		int full_packet_size;
+
+		/* Current IPv4 ID, host endian. */
+		unsigned ipv4_id;
+	} p;
+};
+
+
+/*
+ * Verify that our various assumptions about sk_buffs and the conditions
+ * under which TSO will be attempted hold true.
+ */
+static inline void efx_tso_check_safe(const struct sk_buff *skb)
+{
+	EFX_BUG_ON_PARANOID(skb->protocol != htons(ETH_P_IP));
+	EFX_BUG_ON_PARANOID(((struct ethhdr *)skb->data)->h_proto !=
+			    skb->protocol);
+	EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP);
+	EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data)
+			     + (tcp_hdr(skb)->doff << 2u)) >
+			    skb_headlen(skb));
+}
+
+
+/*
+ * Allocate a page worth of efx_tso_header structures, and string them
+ * into the tx_queue->tso_headers_free linked list. Return 0 or -ENOMEM.
+ */
+static int efx_tsoh_block_alloc(struct efx_tx_queue *tx_queue)
+{
+
+	struct pci_dev *pci_dev = tx_queue->efx->pci_dev;
+	struct efx_tso_header *tsoh;
+	dma_addr_t dma_addr;
+	u8 *base_kva, *kva;
+
+	base_kva = pci_alloc_consistent(pci_dev, PAGE_SIZE, &dma_addr);
+	if (base_kva == NULL) {
+		EFX_ERR(tx_queue->efx, "Unable to allocate page for TSO"
+			" headers\n");
+		return -ENOMEM;
+	}
+
+	/* pci_alloc_consistent() allocates pages. */
+	EFX_BUG_ON_PARANOID(dma_addr & (PAGE_SIZE - 1u));
+
+	for (kva = base_kva; kva < base_kva + PAGE_SIZE; kva += TSOH_STD_SIZE) {
+		tsoh = (struct efx_tso_header *)kva;
+		tsoh->dma_addr = dma_addr + (TSOH_BUFFER(tsoh) - base_kva);
+		tsoh->next = tx_queue->tso_headers_free;
+		tx_queue->tso_headers_free = tsoh;
+	}
+
+	return 0;
+}
+
+
+/* Free up a TSO header, and all others in the same page. */
+static void efx_tsoh_block_free(struct efx_tx_queue *tx_queue,
+				struct efx_tso_header *tsoh,
+				struct pci_dev *pci_dev)
+{
+	struct efx_tso_header **p;
+	unsigned long base_kva;
+	dma_addr_t base_dma;
+
+	base_kva = (unsigned long)tsoh & PAGE_MASK;
+	base_dma = tsoh->dma_addr & PAGE_MASK;
+
+	p = &tx_queue->tso_headers_free;
+	while (*p != NULL)
+		if (((unsigned long)*p & PAGE_MASK) == base_kva)
+			*p = (*p)->next;
+		else
+			p = &(*p)->next;
+
+	pci_free_consistent(pci_dev, PAGE_SIZE, (void *)base_kva, base_dma);
+}
+
+static struct efx_tso_header *
+efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len)
+{
+	struct efx_tso_header *tsoh;
+
+	tsoh = kmalloc(TSOH_SIZE(header_len), GFP_ATOMIC | GFP_DMA);
+	if (unlikely(!tsoh))
+		return NULL;
+
+	tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev,
+					TSOH_BUFFER(tsoh), header_len,
+					PCI_DMA_TODEVICE);
+	if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) {
+		kfree(tsoh);
+		return NULL;
+	}
+
+	tsoh->unmap_len = header_len;
+	return tsoh;
+}
+
+static void
+efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, struct efx_tso_header *tsoh)
+{
+	pci_unmap_single(tx_queue->efx->pci_dev,
+			 tsoh->dma_addr, tsoh->unmap_len,
+			 PCI_DMA_TODEVICE);
+	kfree(tsoh);
+}
+
+/**
+ * efx_tx_queue_insert - push descriptors onto the TX queue
+ * @tx_queue:		Efx TX queue
+ * @dma_addr:		DMA address of fragment
+ * @len:		Length of fragment
+ * @skb:		Only non-null for end of last segment
+ * @end_of_packet:	True if last fragment in a packet
+ * @unmap_addr:		DMA address of fragment for unmapping
+ * @unmap_len:		Only set this in last segment of a fragment
+ *
+ * Push descriptors onto the TX queue.  Return 0 on success or 1 if
+ * @tx_queue full.
+ */
+static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
+			       dma_addr_t dma_addr, unsigned len,
+			       const struct sk_buff *skb, int end_of_packet,
+			       dma_addr_t unmap_addr, unsigned unmap_len)
+{
+	struct efx_tx_buffer *buffer;
+	struct efx_nic *efx = tx_queue->efx;
+	unsigned dma_len, fill_level, insert_ptr, misalign;
+	int q_space;
+
+	EFX_BUG_ON_PARANOID(len <= 0);
+
+	fill_level = tx_queue->insert_count - tx_queue->old_read_count;
+	/* -1 as there is no way to represent all descriptors used */
+	q_space = efx->type->txd_ring_mask - 1 - fill_level;
+
+	while (1) {
+		if (unlikely(q_space-- <= 0)) {
+			/* It might be that completions have happened
+			 * since the xmit path last checked.  Update
+			 * the xmit path's copy of read_count.
+			 */
+			++tx_queue->stopped;
+			/* This memory barrier protects the change of
+			 * stopped from the access of read_count. */
+			smp_mb();
+			tx_queue->old_read_count =
+				*(volatile unsigned *)&tx_queue->read_count;
+			fill_level = (tx_queue->insert_count
+				      - tx_queue->old_read_count);
+			q_space = efx->type->txd_ring_mask - 1 - fill_level;
+			if (unlikely(q_space-- <= 0))
+				return 1;
+			smp_mb();
+			--tx_queue->stopped;
+		}
+
+		insert_ptr = tx_queue->insert_count & efx->type->txd_ring_mask;
+		buffer = &tx_queue->buffer[insert_ptr];
+		++tx_queue->insert_count;
+
+		EFX_BUG_ON_PARANOID(tx_queue->insert_count -
+				    tx_queue->read_count >
+				    efx->type->txd_ring_mask);
+
+		efx_tsoh_free(tx_queue, buffer);
+		EFX_BUG_ON_PARANOID(buffer->len);
+		EFX_BUG_ON_PARANOID(buffer->unmap_len);
+		EFX_BUG_ON_PARANOID(buffer->skb);
+		EFX_BUG_ON_PARANOID(buffer->continuation != 1);
+		EFX_BUG_ON_PARANOID(buffer->tsoh);
+
+		buffer->dma_addr = dma_addr;
+
+		/* Ensure we do not cross a boundary unsupported by H/W */
+		dma_len = (~dma_addr & efx->type->tx_dma_mask) + 1;
+
+		misalign = (unsigned)dma_addr & efx->type->bug5391_mask;
+		if (misalign && dma_len + misalign > 512)
+			dma_len = 512 - misalign;
+
+		/* If there is enough space to send then do so */
+		if (dma_len >= len)
+			break;
+
+		buffer->len = dma_len; /* Don't set the other members */
+		dma_addr += dma_len;
+		len -= dma_len;
+	}
+
+	EFX_BUG_ON_PARANOID(!len);
+	buffer->len = len;
+	buffer->skb = skb;
+	buffer->continuation = !end_of_packet;
+	buffer->unmap_addr = unmap_addr;
+	buffer->unmap_len = unmap_len;
+	return 0;
+}
+
+
+/*
+ * Put a TSO header into the TX queue.
+ *
+ * This is special-cased because we know that it is small enough to fit in
+ * a single fragment, and we know it doesn't cross a page boundary.  It
+ * also allows us to not worry about end-of-packet etc.
+ */
+static inline void efx_tso_put_header(struct efx_tx_queue *tx_queue,
+				      struct efx_tso_header *tsoh, unsigned len)
+{
+	struct efx_tx_buffer *buffer;
+
+	buffer = &tx_queue->buffer[tx_queue->insert_count &
+				   tx_queue->efx->type->txd_ring_mask];
+	efx_tsoh_free(tx_queue, buffer);
+	EFX_BUG_ON_PARANOID(buffer->len);
+	EFX_BUG_ON_PARANOID(buffer->unmap_len);
+	EFX_BUG_ON_PARANOID(buffer->skb);
+	EFX_BUG_ON_PARANOID(buffer->continuation != 1);
+	EFX_BUG_ON_PARANOID(buffer->tsoh);
+	buffer->len = len;
+	buffer->dma_addr = tsoh->dma_addr;
+	buffer->tsoh = tsoh;
+
+	++tx_queue->insert_count;
+}
+
+
+/* Remove descriptors put into a tx_queue. */
+static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
+{
+	struct efx_tx_buffer *buffer;
+
+	/* Work backwards until we hit the original insert pointer value */
+	while (tx_queue->insert_count != tx_queue->write_count) {
+		--tx_queue->insert_count;
+		buffer = &tx_queue->buffer[tx_queue->insert_count &
+					   tx_queue->efx->type->txd_ring_mask];
+		efx_tsoh_free(tx_queue, buffer);
+		EFX_BUG_ON_PARANOID(buffer->skb);
+		buffer->len = 0;
+		buffer->continuation = 1;
+		if (buffer->unmap_len) {
+			pci_unmap_page(tx_queue->efx->pci_dev,
+				       buffer->unmap_addr,
+				       buffer->unmap_len, PCI_DMA_TODEVICE);
+			buffer->unmap_len = 0;
+		}
+	}
+}
+
+
+/* Parse the SKB header and initialise state. */
+static inline void tso_start(struct tso_state *st, const struct sk_buff *skb)
+{
+	/* All ethernet/IP/TCP headers combined size is TCP header size
+	 * plus offset of TCP header relative to start of packet.
+	 */
+	st->p.header_length = ((tcp_hdr(skb)->doff << 2u)
+			       + PTR_DIFF(tcp_hdr(skb), skb->data));
+	st->p.full_packet_size = (st->p.header_length
+				  + skb_shinfo(skb)->gso_size);
+
+	st->p.ipv4_id = ntohs(ip_hdr(skb)->id);
+	st->seqnum = ntohl(tcp_hdr(skb)->seq);
+
+	EFX_BUG_ON_PARANOID(tcp_hdr(skb)->urg);
+	EFX_BUG_ON_PARANOID(tcp_hdr(skb)->syn);
+	EFX_BUG_ON_PARANOID(tcp_hdr(skb)->rst);
+
+	st->packet_space = st->p.full_packet_size;
+	st->remaining_len = skb->len - st->p.header_length;
+}
+
+
+/**
+ * tso_get_fragment - record fragment details and map for DMA
+ * @st:			TSO state
+ * @efx:		Efx NIC
+ * @data:		Pointer to fragment data
+ * @len:		Length of fragment
+ *
+ * Record fragment details and map for DMA.  Return 0 on success, or
+ * -%ENOMEM if DMA mapping fails.
+ */
+static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx,
+				   int len, struct page *page, int page_off)
+{
+
+	st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off,
+					  len, PCI_DMA_TODEVICE);
+	if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) {
+		st->ifc.unmap_len = len;
+		st->ifc.len = len;
+		st->ifc.dma_addr = st->ifc.unmap_addr;
+		st->ifc.page = page;
+		st->ifc.page_off = page_off;
+		return 0;
+	}
+	return -ENOMEM;
+}
+
+
+/**
+ * tso_fill_packet_with_fragment - form descriptors for the current fragment
+ * @tx_queue:		Efx TX queue
+ * @skb:		Socket buffer
+ * @st:			TSO state
+ *
+ * Form descriptors for the current fragment, until we reach the end
+ * of fragment or end-of-packet.  Return 0 on success, 1 if not enough
+ * space in @tx_queue.
+ */
+static inline int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue,
+						const struct sk_buff *skb,
+						struct tso_state *st)
+{
+
+	int n, end_of_packet, rc;
+
+	if (st->ifc.len == 0)
+		return 0;
+	if (st->packet_space == 0)
+		return 0;
+
+	EFX_BUG_ON_PARANOID(st->ifc.len <= 0);
+	EFX_BUG_ON_PARANOID(st->packet_space <= 0);
+
+	n = min(st->ifc.len, st->packet_space);
+
+	st->packet_space -= n;
+	st->remaining_len -= n;
+	st->ifc.len -= n;
+	st->ifc.page_off += n;
+	end_of_packet = st->remaining_len == 0 || st->packet_space == 0;
+
+	rc = efx_tx_queue_insert(tx_queue, st->ifc.dma_addr, n,
+				 st->remaining_len ? NULL : skb,
+				 end_of_packet, st->ifc.unmap_addr,
+				 st->ifc.len ? 0 : st->ifc.unmap_len);
+
+	st->ifc.dma_addr += n;
+
+	return rc;
+}
+
+
+/**
+ * tso_start_new_packet - generate a new header and prepare for the new packet
+ * @tx_queue:		Efx TX queue
+ * @skb:		Socket buffer
+ * @st:			TSO state
+ *
+ * Generate a new header and prepare for the new packet.  Return 0 on
+ * success, or -1 if failed to alloc header.
+ */
+static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue,
+				       const struct sk_buff *skb,
+				       struct tso_state *st)
+{
+	struct efx_tso_header *tsoh;
+	struct iphdr *tsoh_iph;
+	struct tcphdr *tsoh_th;
+	unsigned ip_length;
+	u8 *header;
+
+	/* Allocate a DMA-mapped header buffer. */
+	if (likely(TSOH_SIZE(st->p.header_length) <= TSOH_STD_SIZE)) {
+		if (tx_queue->tso_headers_free == NULL)
+			if (efx_tsoh_block_alloc(tx_queue))
+				return -1;
+		EFX_BUG_ON_PARANOID(!tx_queue->tso_headers_free);
+		tsoh = tx_queue->tso_headers_free;
+		tx_queue->tso_headers_free = tsoh->next;
+		tsoh->unmap_len = 0;
+	} else {
+		tx_queue->tso_long_headers++;
+		tsoh = efx_tsoh_heap_alloc(tx_queue, st->p.header_length);
+		if (unlikely(!tsoh))
+			return -1;
+	}
+
+	header = TSOH_BUFFER(tsoh);
+	tsoh_th = (struct tcphdr *)(header + SKB_TCP_OFF(skb));
+	tsoh_iph = (struct iphdr *)(header + SKB_IPV4_OFF(skb));
+
+	/* Copy and update the headers. */
+	memcpy(header, skb->data, st->p.header_length);
+
+	tsoh_th->seq = htonl(st->seqnum);
+	st->seqnum += skb_shinfo(skb)->gso_size;
+	if (st->remaining_len > skb_shinfo(skb)->gso_size) {
+		/* This packet will not finish the TSO burst. */
+		ip_length = st->p.full_packet_size - ETH_HDR_LEN(skb);
+		tsoh_th->fin = 0;
+		tsoh_th->psh = 0;
+	} else {
+		/* This packet will be the last in the TSO burst. */
+		ip_length = (st->p.header_length - ETH_HDR_LEN(skb)
+			     + st->remaining_len);
+		tsoh_th->fin = tcp_hdr(skb)->fin;
+		tsoh_th->psh = tcp_hdr(skb)->psh;
+	}
+	tsoh_iph->tot_len = htons(ip_length);
+
+	/* Linux leaves suitable gaps in the IP ID space for us to fill. */
+	tsoh_iph->id = htons(st->p.ipv4_id);
+	st->p.ipv4_id++;
+
+	st->packet_space = skb_shinfo(skb)->gso_size;
+	++tx_queue->tso_packets;
+
+	/* Form a descriptor for this header. */
+	efx_tso_put_header(tx_queue, tsoh, st->p.header_length);
+
+	return 0;
+}
+
+
+/**
+ * efx_enqueue_skb_tso - segment and transmit a TSO socket buffer
+ * @tx_queue:		Efx TX queue
+ * @skb:		Socket buffer
+ *
+ * Context: You must hold netif_tx_lock() to call this function.
+ *
+ * Add socket buffer @skb to @tx_queue, doing TSO or return != 0 if
+ * @skb was not enqueued.  In all cases @skb is consumed.  Return
+ * %NETDEV_TX_OK or %NETDEV_TX_BUSY.
+ */
+static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
+			       const struct sk_buff *skb)
+{
+	int frag_i, rc, rc2 = NETDEV_TX_OK;
+	struct tso_state state;
+	skb_frag_t *f;
+
+	/* Verify TSO is safe - these checks should never fail. */
+	efx_tso_check_safe(skb);
+
+	EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
+
+	tso_start(&state, skb);
+
+	/* Assume that skb header area contains exactly the headers, and
+	 * all payload is in the frag list.
+	 */
+	if (skb_headlen(skb) == state.p.header_length) {
+		/* Grab the first payload fragment. */
+		EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags < 1);
+		frag_i = 0;
+		f = &skb_shinfo(skb)->frags[frag_i];
+		rc = tso_get_fragment(&state, tx_queue->efx,
+				      f->size, f->page, f->page_offset);
+		if (rc)
+			goto mem_err;
+	} else {
+		/* It may look like this code fragment assumes that the
+		 * skb->data portion does not cross a page boundary, but
+		 * that is not the case.  It is guaranteed to be direct
+		 * mapped memory, and therefore is physically contiguous,
+		 * and so DMA will work fine.  kmap_atomic() on this region
+		 * will just return the direct mapping, so that will work
+		 * too.
+		 */
+		int page_off = (unsigned long)skb->data & (PAGE_SIZE - 1);
+		int hl = state.p.header_length;
+		rc = tso_get_fragment(&state, tx_queue->efx,
+				      skb_headlen(skb) - hl,
+				      virt_to_page(skb->data), page_off + hl);
+		if (rc)
+			goto mem_err;
+		frag_i = -1;
+	}
+
+	if (tso_start_new_packet(tx_queue, skb, &state) < 0)
+		goto mem_err;
+
+	while (1) {
+		rc = tso_fill_packet_with_fragment(tx_queue, skb, &state);
+		if (unlikely(rc))
+			goto stop;
+
+		/* Move onto the next fragment? */
+		if (state.ifc.len == 0) {
+			if (++frag_i >= skb_shinfo(skb)->nr_frags)
+				/* End of payload reached. */
+				break;
+			f = &skb_shinfo(skb)->frags[frag_i];
+			rc = tso_get_fragment(&state, tx_queue->efx,
+					      f->size, f->page, f->page_offset);
+			if (rc)
+				goto mem_err;
+		}
+
+		/* Start at new packet? */
+		if (state.packet_space == 0 &&
+		    tso_start_new_packet(tx_queue, skb, &state) < 0)
+			goto mem_err;
+	}
+
+	/* Pass off to hardware */
+	falcon_push_buffers(tx_queue);
+
+	tx_queue->tso_bursts++;
+	return NETDEV_TX_OK;
+
+ mem_err:
+	EFX_ERR(tx_queue->efx, "Out of memory for TSO headers, or PCI mapping"
+		" error\n");
+	dev_kfree_skb_any((struct sk_buff *)skb);
+	goto unwind;
+
+ stop:
+	rc2 = NETDEV_TX_BUSY;
+
+	/* Stop the queue if it wasn't stopped before. */
+	if (tx_queue->stopped == 1)
+		efx_stop_queue(tx_queue->efx);
+
+ unwind:
+	efx_enqueue_unwind(tx_queue);
+	return rc2;
+}
+
+
+/*
+ * Free up all TSO datastructures associated with tx_queue. This
+ * routine should be called only once the tx_queue is both empty and
+ * will no longer be used.
+ */
+static void efx_fini_tso(struct efx_tx_queue *tx_queue)
+{
+	unsigned i;
+
+	if (tx_queue->buffer)
+		for (i = 0; i <= tx_queue->efx->type->txd_ring_mask; ++i)
+			efx_tsoh_free(tx_queue, &tx_queue->buffer[i]);
+
+	while (tx_queue->tso_headers_free != NULL)
+		efx_tsoh_block_free(tx_queue, tx_queue->tso_headers_free,
+				    tx_queue->efx->pci_dev);
+}
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 66dd5bf..3b9f9dd 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -24,6 +24,10 @@
 			   MDIO_MMDREG_DEVS0_PMAPMD |	\
 			   MDIO_MMDREG_DEVS0_PHYXS)
 
+#define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) |		\
+		       (1 << LOOPBACK_PMAPMD) |		\
+		       (1 << LOOPBACK_NETWORK))
+
 /****************************************************************************/
 /* Quake-specific MDIO registers */
 #define MDIO_QUAKE_LED0_REG	(0xD006)
@@ -35,6 +39,10 @@
 			    mode);
 }
 
+struct xfp_phy_data {
+	int tx_disabled;
+};
+
 #define XFP_MAX_RESET_TIME 500
 #define XFP_RESET_WAIT 10
 
@@ -72,18 +80,31 @@
 
 static int xfp_phy_init(struct efx_nic *efx)
 {
+	struct xfp_phy_data *phy_data;
 	u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS);
 	int rc;
 
+	phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
+	efx->phy_data = (void *) phy_data;
+
 	EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision"
 		 " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
 		 MDIO_ID_REV(devid));
 
+	phy_data->tx_disabled = efx->tx_disabled;
+
 	rc = xfp_reset_phy(efx);
 
 	EFX_INFO(efx, "XFP: PHY init %s.\n",
 		 rc ? "failed" : "successful");
+	if (rc < 0)
+		goto fail;
 
+	return 0;
+
+ fail:
+	kfree(efx->phy_data);
+	efx->phy_data = NULL;
 	return rc;
 }
 
@@ -110,6 +131,16 @@
 
 static void xfp_phy_reconfigure(struct efx_nic *efx)
 {
+	struct xfp_phy_data *phy_data = efx->phy_data;
+
+	/* Reset the PHY when moving from tx off to tx on */
+	if (phy_data->tx_disabled && !efx->tx_disabled)
+		xfp_reset_phy(efx);
+
+	mdio_clause45_transmit_disable(efx);
+	mdio_clause45_phy_reconfigure(efx);
+
+	phy_data->tx_disabled = efx->tx_disabled;
 	efx->link_up = xfp_link_ok(efx);
 	efx->link_options = GM_LPA_10000FULL;
 }
@@ -119,6 +150,10 @@
 {
 	/* Clobber the LED if it was blinking */
 	efx->board_info.blink(efx, 0);
+
+	/* Free the context block */
+	kfree(efx->phy_data);
+	efx->phy_data = NULL;
 }
 
 struct efx_phy_operations falcon_xfp_phy_ops = {
@@ -129,4 +164,5 @@
 	.clear_interrupt = xfp_phy_clear_interrupt,
 	.reset_xaui      = efx_port_dummy_op_void,
 	.mmds            = XFP_REQUIRED_DEVS,
+	.loopbacks       = XFP_LOOPBACKS,
 };
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 7bb3ba9..c0a5eea 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1966,13 +1966,13 @@
 struct tx_ring_info {
 	struct sk_buff	*skb;
 	DECLARE_PCI_UNMAP_ADDR(mapaddr);
-	DECLARE_PCI_UNMAP_ADDR(maplen);
+	DECLARE_PCI_UNMAP_LEN(maplen);
 };
 
 struct rx_ring_info {
 	struct sk_buff	*skb;
 	dma_addr_t	data_addr;
-	DECLARE_PCI_UNMAP_ADDR(data_size);
+	DECLARE_PCI_UNMAP_LEN(data_size);
 	dma_addr_t	frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
 };
 
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index a59c1f2..2511ca7 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -434,10 +434,6 @@
 
 	ULI526X_DBUG(0, "uli526x_open", 0);
 
-	ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev);
-	if (ret)
-		return ret;
-
 	/* system variable init */
 	db->cr6_data = CR6_DEFAULT | uli526x_cr6_user_set;
 	db->tx_packet_cnt = 0;
@@ -456,6 +452,10 @@
 	/* Initialize ULI526X board */
 	uli526x_init(dev);
 
+	ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev);
+	if (ret)
+		return ret;
+
 	/* Active System Interface */
 	netif_wake_queue(dev);
 
@@ -1368,6 +1368,12 @@
  *	This setup frame initialize ULI526X address filter mode
  */
 
+#ifdef __BIG_ENDIAN
+#define FLT_SHIFT 16
+#else
+#define FLT_SHIFT 0
+#endif
+
 static void send_filter_frame(struct net_device *dev, int mc_cnt)
 {
 	struct uli526x_board_info *db = netdev_priv(dev);
@@ -1384,27 +1390,27 @@
 
 	/* Node address */
 	addrptr = (u16 *) dev->dev_addr;
-	*suptr++ = addrptr[0];
-	*suptr++ = addrptr[1];
-	*suptr++ = addrptr[2];
+	*suptr++ = addrptr[0] << FLT_SHIFT;
+	*suptr++ = addrptr[1] << FLT_SHIFT;
+	*suptr++ = addrptr[2] << FLT_SHIFT;
 
 	/* broadcast address */
-	*suptr++ = 0xffff;
-	*suptr++ = 0xffff;
-	*suptr++ = 0xffff;
+	*suptr++ = 0xffff << FLT_SHIFT;
+	*suptr++ = 0xffff << FLT_SHIFT;
+	*suptr++ = 0xffff << FLT_SHIFT;
 
 	/* fit the multicast address */
 	for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
 		addrptr = (u16 *) mcptr->dmi_addr;
-		*suptr++ = addrptr[0];
-		*suptr++ = addrptr[1];
-		*suptr++ = addrptr[2];
+		*suptr++ = addrptr[0] << FLT_SHIFT;
+		*suptr++ = addrptr[1] << FLT_SHIFT;
+		*suptr++ = addrptr[2] << FLT_SHIFT;
 	}
 
 	for (; i<14; i++) {
-		*suptr++ = 0xffff;
-		*suptr++ = 0xffff;
-		*suptr++ = 0xffff;
+		*suptr++ = 0xffff << FLT_SHIFT;
+		*suptr++ = 0xffff << FLT_SHIFT;
+		*suptr++ = 0xffff << FLT_SHIFT;
 	}
 
 	/* prepare the setup frame */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 281ce3d..ca0bdac 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -62,7 +62,6 @@
 #endif				/* UGETH_VERBOSE_DEBUG */
 #define UGETH_MSG_DEFAULT	(NETIF_MSG_IFUP << 1 ) - 1
 
-void uec_set_ethtool_ops(struct net_device *netdev);
 
 static DEFINE_SPINLOCK(ugeth_lock);
 
@@ -216,7 +215,8 @@
 	}
 }
 
-static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd)
+static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
+		u8 __iomem *bd)
 {
 	struct sk_buff *skb = NULL;
 
@@ -236,21 +236,22 @@
 
 	skb->dev = ugeth->dev;
 
-	out_be32(&((struct qe_bd *)bd)->buf,
+	out_be32(&((struct qe_bd __iomem *)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));
 
-	out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W)));
+	out_be32((u32 __iomem *)bd,
+			(R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W)));
 
 	return skb;
 }
 
 static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ)
 {
-	u8 *bd;
+	u8 __iomem *bd;
 	u32 bd_status;
 	struct sk_buff *skb;
 	int i;
@@ -259,7 +260,7 @@
 	i = 0;
 
 	do {
-		bd_status = in_be32((u32*)bd);
+		bd_status = in_be32((u32 __iomem *)bd);
 		skb = get_new_skb(ugeth, bd);
 
 		if (!skb)	/* If can not allocate data buffer,
@@ -277,7 +278,7 @@
 }
 
 static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
-				  volatile u32 *p_start,
+				  u32 *p_start,
 				  u8 num_entries,
 				  u32 thread_size,
 				  u32 thread_alignment,
@@ -316,7 +317,7 @@
 }
 
 static int return_init_enet_entries(struct ucc_geth_private *ugeth,
-				    volatile u32 *p_start,
+				    u32 *p_start,
 				    u8 num_entries,
 				    enum qe_risc_allocation risc,
 				    int skip_page_for_first_entry)
@@ -326,21 +327,22 @@
 	int snum;
 
 	for (i = 0; i < num_entries; i++) {
+		u32 val = *p_start;
+
 		/* Check that this entry was actually valid --
 		needed in case failed in allocations */
-		if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+		if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) {
 			snum =
-			    (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+			    (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >>
 			    ENET_INIT_PARAM_SNUM_SHIFT;
 			qe_put_snum((u8) snum);
 			if (!((i == 0) && skip_page_for_first_entry)) {
 			/* First entry of Rx does not have page */
 				init_enet_offset =
-				    (in_be32(p_start) &
-				     ENET_INIT_PARAM_PTR_MASK);
+				    (val & ENET_INIT_PARAM_PTR_MASK);
 				qe_muram_free(init_enet_offset);
 			}
-			*(p_start++) = 0;	/* Just for cosmetics */
+			*p_start++ = 0;
 		}
 	}
 
@@ -349,7 +351,7 @@
 
 #ifdef DEBUG
 static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
-				  volatile u32 *p_start,
+				  u32 __iomem *p_start,
 				  u8 num_entries,
 				  u32 thread_size,
 				  enum qe_risc_allocation risc,
@@ -360,11 +362,13 @@
 	int snum;
 
 	for (i = 0; i < num_entries; i++) {
+		u32 val = in_be32(p_start);
+
 		/* Check that this entry was actually valid --
 		needed in case failed in allocations */
-		if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+		if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) {
 			snum =
-			    (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+			    (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >>
 			    ENET_INIT_PARAM_SNUM_SHIFT;
 			qe_put_snum((u8) snum);
 			if (!((i == 0) && skip_page_for_first_entry)) {
@@ -440,7 +444,7 @@
 
 static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 
 	if (!(paddr_num < NUM_OF_PADDRS)) {
 		ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
@@ -448,7 +452,7 @@
 	}
 
 	p_82xx_addr_filt =
-	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	/* Writing address ff.ff.ff.ff.ff.ff disables address
@@ -463,11 +467,11 @@
 static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
                                 u8 *p_enet_addr)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 	u32 cecr_subblock;
 
 	p_82xx_addr_filt =
-	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	cecr_subblock =
@@ -487,7 +491,7 @@
 static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
 {
 	struct ucc_fast_private *uccf;
-	struct ucc_geth *ug_regs;
+	struct ucc_geth __iomem *ug_regs;
 	u32 maccfg2, uccm;
 
 	uccf = ugeth->uccf;
@@ -507,7 +511,7 @@
 static void magic_packet_detection_disable(struct ucc_geth_private *ugeth)
 {
 	struct ucc_fast_private *uccf;
-	struct ucc_geth *ug_regs;
+	struct ucc_geth __iomem *ug_regs;
 	u32 maccfg2, uccm;
 
 	uccf = ugeth->uccf;
@@ -538,13 +542,13 @@
 			   rx_firmware_statistics,
 			   struct ucc_geth_hardware_statistics *hardware_statistics)
 {
-	struct ucc_fast *uf_regs;
-	struct ucc_geth *ug_regs;
+	struct ucc_fast __iomem *uf_regs;
+	struct ucc_geth __iomem *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 = (struct ucc_fast *) ug_regs;
+	uf_regs = (struct ucc_fast __iomem *) ug_regs;
 	p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram;
 	p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram;
 
@@ -1132,9 +1136,9 @@
 }
 #endif /* DEBUG */
 
-static void init_default_reg_vals(volatile u32 *upsmr_register,
-				  volatile u32 *maccfg1_register,
-				  volatile u32 *maccfg2_register)
+static void init_default_reg_vals(u32 __iomem *upsmr_register,
+				  u32 __iomem *maccfg1_register,
+				  u32 __iomem *maccfg2_register)
 {
 	out_be32(upsmr_register, UCC_GETH_UPSMR_INIT);
 	out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT);
@@ -1148,7 +1152,7 @@
 				   u8 alt_beb_truncation,
 				   u8 max_retransmissions,
 				   u8 collision_window,
-				   volatile u32 *hafdup_register)
+				   u32 __iomem *hafdup_register)
 {
 	u32 value = 0;
 
@@ -1180,7 +1184,7 @@
 				       u8 non_btb_ipg,
 				       u8 min_ifg,
 				       u8 btb_ipg,
-				       volatile u32 *ipgifg_register)
+				       u32 __iomem *ipgifg_register)
 {
 	u32 value = 0;
 
@@ -1215,9 +1219,9 @@
 				    int tx_flow_control_enable,
 				    u16 pause_period,
 				    u16 extension_field,
-				    volatile u32 *upsmr_register,
-				    volatile u32 *uempr_register,
-				    volatile u32 *maccfg1_register)
+				    u32 __iomem *upsmr_register,
+				    u32 __iomem *uempr_register,
+				    u32 __iomem *maccfg1_register)
 {
 	u32 value = 0;
 
@@ -1243,8 +1247,8 @@
 
 static int init_hw_statistics_gathering_mode(int enable_hardware_statistics,
 					     int auto_zero_hardware_statistics,
-					     volatile u32 *upsmr_register,
-					     volatile u16 *uescr_register)
+					     u32 __iomem *upsmr_register,
+					     u16 __iomem *uescr_register)
 {
 	u32 upsmr_value = 0;
 	u16 uescr_value = 0;
@@ -1270,12 +1274,12 @@
 static int init_firmware_statistics_gathering_mode(int
 		enable_tx_firmware_statistics,
 		int enable_rx_firmware_statistics,
-		volatile u32 *tx_rmon_base_ptr,
+		u32 __iomem *tx_rmon_base_ptr,
 		u32 tx_firmware_statistics_structure_address,
-		volatile u32 *rx_rmon_base_ptr,
+		u32 __iomem *rx_rmon_base_ptr,
 		u32 rx_firmware_statistics_structure_address,
-		volatile u16 *temoder_register,
-		volatile u32 *remoder_register)
+		u16 __iomem *temoder_register,
+		u32 __iomem *remoder_register)
 {
 	/* Note: this function does not check if */
 	/* the parameters it receives are NULL   */
@@ -1307,8 +1311,8 @@
 				      u8 address_byte_3,
 				      u8 address_byte_4,
 				      u8 address_byte_5,
-				      volatile u32 *macstnaddr1_register,
-				      volatile u32 *macstnaddr2_register)
+				      u32 __iomem *macstnaddr1_register,
+				      u32 __iomem *macstnaddr2_register)
 {
 	u32 value = 0;
 
@@ -1344,7 +1348,7 @@
 }
 
 static int init_check_frame_length_mode(int length_check,
-					volatile u32 *maccfg2_register)
+					u32 __iomem *maccfg2_register)
 {
 	u32 value = 0;
 
@@ -1360,7 +1364,7 @@
 }
 
 static int init_preamble_length(u8 preamble_length,
-				volatile u32 *maccfg2_register)
+				u32 __iomem *maccfg2_register)
 {
 	u32 value = 0;
 
@@ -1376,7 +1380,7 @@
 
 static int init_rx_parameters(int reject_broadcast,
 			      int receive_short_frames,
-			      int promiscuous, volatile u32 *upsmr_register)
+			      int promiscuous, u32 __iomem *upsmr_register)
 {
 	u32 value = 0;
 
@@ -1403,7 +1407,7 @@
 }
 
 static int init_max_rx_buff_len(u16 max_rx_buf_len,
-				volatile u16 *mrblr_register)
+				u16 __iomem *mrblr_register)
 {
 	/* max_rx_buf_len value must be a multiple of 128 */
 	if ((max_rx_buf_len == 0)
@@ -1415,8 +1419,8 @@
 }
 
 static int init_min_frame_len(u16 min_frame_length,
-			      volatile u16 *minflr_register,
-			      volatile u16 *mrblr_register)
+			      u16 __iomem *minflr_register,
+			      u16 __iomem *mrblr_register)
 {
 	u16 mrblr_value = 0;
 
@@ -1431,8 +1435,8 @@
 static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 {
 	struct ucc_geth_info *ug_info;
-	struct ucc_geth *ug_regs;
-	struct ucc_fast *uf_regs;
+	struct ucc_geth __iomem *ug_regs;
+	struct ucc_fast __iomem *uf_regs;
 	int ret_val;
 	u32 upsmr, maccfg2, tbiBaseAddress;
 	u16 value;
@@ -1517,8 +1521,8 @@
 static void adjust_link(struct net_device *dev)
 {
 	struct ucc_geth_private *ugeth = netdev_priv(dev);
-	struct ucc_geth *ug_regs;
-	struct ucc_fast *uf_regs;
+	struct ucc_geth __iomem *ug_regs;
+	struct ucc_fast __iomem *uf_regs;
 	struct phy_device *phydev = ugeth->phydev;
 	unsigned long flags;
 	int new_state = 0;
@@ -1678,9 +1682,9 @@
 	uccf = ugeth->uccf;
 
 	/* Clear acknowledge bit */
-	temp = ugeth->p_rx_glbl_pram->rxgstpack;
+	temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
 	temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX;
-	ugeth->p_rx_glbl_pram->rxgstpack = temp;
+	out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp);
 
 	/* Keep issuing command and checking acknowledge bit until
 	it is asserted, according to spec */
@@ -1692,7 +1696,7 @@
 		qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
 			     QE_CR_PROTOCOL_ETHERNET, 0);
 
-		temp = ugeth->p_rx_glbl_pram->rxgstpack;
+		temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
 	} while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX));
 
 	uccf->stopped_rx = 1;
@@ -1991,19 +1995,20 @@
 						       enum enet_addr_type
 						       enet_addr_type)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *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;
+	u32 __iomem *addr_h;
+	u32 __iomem *addr_l;
 	u8 *p_counter;
 
 	uccf = ugeth->uccf;
 
 	p_82xx_addr_filt =
-	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
-	    addressfiltering;
+	    (struct ucc_geth_82xx_address_filtering_pram __iomem *)
+	    ugeth->p_rx_glbl_pram->addressfiltering;
 
 	if (enet_addr_type == ENET_ADDR_TYPE_GROUP) {
 		addr_h = &(p_82xx_addr_filt->gaddr_h);
@@ -2079,7 +2084,7 @@
 static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 {
 	u16 i, j;
-	u8 *bd;
+	u8 __iomem *bd;
 
 	if (!ugeth)
 		return;
@@ -2154,8 +2159,8 @@
 		for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
 			if (ugeth->tx_skbuff[i][j]) {
 				dma_unmap_single(NULL,
-						 ((struct qe_bd *)bd)->buf,
-						 (in_be32((u32 *)bd) &
+						 in_be32(&((struct qe_bd __iomem *)bd)->buf),
+						 (in_be32((u32 __iomem *)bd) &
 						  BD_LENGTH_MASK),
 						 DMA_TO_DEVICE);
 				dev_kfree_skb_any(ugeth->tx_skbuff[i][j]);
@@ -2182,7 +2187,7 @@
 			for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
 				if (ugeth->rx_skbuff[i][j]) {
 					dma_unmap_single(NULL,
-						((struct qe_bd *)bd)->buf,
+						in_be32(&((struct qe_bd __iomem *)bd)->buf),
 						ugeth->ug_info->
 						uf_info.max_rx_buf_length +
 						UCC_GETH_RX_DATA_BUF_ALIGNMENT,
@@ -2218,8 +2223,8 @@
 {
 	struct ucc_geth_private *ugeth;
 	struct dev_mc_list *dmi;
-	struct ucc_fast *uf_regs;
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_fast __iomem *uf_regs;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 	int i;
 
 	ugeth = netdev_priv(dev);
@@ -2228,14 +2233,14 @@
 
 	if (dev->flags & IFF_PROMISC) {
 
-		uf_regs->upsmr |= UPSMR_PRO;
+		out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr) | UPSMR_PRO);
 
 	} else {
 
-		uf_regs->upsmr &= ~UPSMR_PRO;
+		out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr)&~UPSMR_PRO);
 
 		p_82xx_addr_filt =
-		    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
+		    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->
 		    p_rx_glbl_pram->addressfiltering;
 
 		if (dev->flags & IFF_ALLMULTI) {
@@ -2270,7 +2275,7 @@
 
 static void ucc_geth_stop(struct ucc_geth_private *ugeth)
 {
-	struct ucc_geth *ug_regs = ugeth->ug_regs;
+	struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
 	struct phy_device *phydev = ugeth->phydev;
 	u32 tempval;
 
@@ -2419,20 +2424,20 @@
 		return -ENOMEM;
 	}
 
-	ugeth->ug_regs = (struct ucc_geth *) ioremap(uf_info->regs, sizeof(struct ucc_geth));
+	ugeth->ug_regs = (struct ucc_geth __iomem *) ioremap(uf_info->regs, sizeof(struct ucc_geth));
 
 	return 0;
 }
 
 static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
-	struct ucc_geth_init_pram *p_init_enet_pram;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
+	struct ucc_geth_init_pram __iomem *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;
+	struct ucc_fast __iomem *uf_regs;
+	struct ucc_geth __iomem *ug_regs;
 	int ret_val = -EINVAL;
 	u32 remoder = UCC_GETH_REMODER_INIT;
 	u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
@@ -2440,7 +2445,8 @@
 	u16 temoder = UCC_GETH_TEMODER_INIT;
 	u16 test;
 	u8 function_code = 0;
-	u8 *bd, *endOfRing;
+	u8 __iomem *bd;
+	u8 __iomem *endOfRing;
 	u8 numThreadsRxNumerical, numThreadsTxNumerical;
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -2602,11 +2608,11 @@
 			if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4)
 				align = UCC_GETH_TX_BD_RING_ALIGNMENT;
 			ugeth->tx_bd_ring_offset[j] =
-				kmalloc((u32) (length + align), GFP_KERNEL);
+				(u32) kmalloc((u32) (length + align), GFP_KERNEL);
 
 			if (ugeth->tx_bd_ring_offset[j] != 0)
 				ugeth->p_tx_bd_ring[j] =
-					(void*)((ugeth->tx_bd_ring_offset[j] +
+					(u8 __iomem *)((ugeth->tx_bd_ring_offset[j] +
 					align) & ~(align - 1));
 		} else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
 			ugeth->tx_bd_ring_offset[j] =
@@ -2614,7 +2620,7 @@
 					   UCC_GETH_TX_BD_RING_ALIGNMENT);
 			if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j]))
 				ugeth->p_tx_bd_ring[j] =
-				    (u8 *) qe_muram_addr(ugeth->
+				    (u8 __iomem *) qe_muram_addr(ugeth->
 							 tx_bd_ring_offset[j]);
 		}
 		if (!ugeth->p_tx_bd_ring[j]) {
@@ -2626,8 +2632,8 @@
 			return -ENOMEM;
 		}
 		/* Zero unused end of bd ring, according to spec */
-		memset(ugeth->p_tx_bd_ring[j] +
-		       ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0,
+		memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] +
+		       ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0,
 		       length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd));
 	}
 
@@ -2639,10 +2645,10 @@
 			if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4)
 				align = UCC_GETH_RX_BD_RING_ALIGNMENT;
 			ugeth->rx_bd_ring_offset[j] =
-				kmalloc((u32) (length + align), GFP_KERNEL);
+				(u32) kmalloc((u32) (length + align), GFP_KERNEL);
 			if (ugeth->rx_bd_ring_offset[j] != 0)
 				ugeth->p_rx_bd_ring[j] =
-					(void*)((ugeth->rx_bd_ring_offset[j] +
+					(u8 __iomem *)((ugeth->rx_bd_ring_offset[j] +
 					align) & ~(align - 1));
 		} else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
 			ugeth->rx_bd_ring_offset[j] =
@@ -2650,7 +2656,7 @@
 					   UCC_GETH_RX_BD_RING_ALIGNMENT);
 			if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j]))
 				ugeth->p_rx_bd_ring[j] =
-				    (u8 *) qe_muram_addr(ugeth->
+				    (u8 __iomem *) qe_muram_addr(ugeth->
 							 rx_bd_ring_offset[j]);
 		}
 		if (!ugeth->p_rx_bd_ring[j]) {
@@ -2685,14 +2691,14 @@
 		bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j];
 		for (i = 0; i < ug_info->bdRingLenTx[j]; i++) {
 			/* clear bd buffer */
-			out_be32(&((struct qe_bd *)bd)->buf, 0);
+			out_be32(&((struct qe_bd __iomem *)bd)->buf, 0);
 			/* set bd status and length */
-			out_be32((u32 *)bd, 0);
+			out_be32((u32 __iomem *)bd, 0);
 			bd += sizeof(struct qe_bd);
 		}
 		bd -= sizeof(struct qe_bd);
 		/* set bd status and length */
-		out_be32((u32 *)bd, T_W);	/* for last BD set Wrap bit */
+		out_be32((u32 __iomem *)bd, T_W); /* for last BD set Wrap bit */
 	}
 
 	/* Init Rx bds */
@@ -2717,14 +2723,14 @@
 		bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
 		for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
 			/* set bd status and length */
-			out_be32((u32 *)bd, R_I);
+			out_be32((u32 __iomem *)bd, R_I);
 			/* clear bd buffer */
-			out_be32(&((struct qe_bd *)bd)->buf, 0);
+			out_be32(&((struct qe_bd __iomem *)bd)->buf, 0);
 			bd += sizeof(struct qe_bd);
 		}
 		bd -= sizeof(struct qe_bd);
 		/* set bd status and length */
-		out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */
+		out_be32((u32 __iomem *)bd, R_W); /* for last BD set Wrap bit */
 	}
 
 	/*
@@ -2744,10 +2750,10 @@
 		return -ENOMEM;
 	}
 	ugeth->p_tx_glbl_pram =
-	    (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_tx_global_pram __iomem *) qe_muram_addr(ugeth->
 							tx_glbl_pram_offset);
 	/* Zero out p_tx_glbl_pram */
-	memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram));
+	memset_io((void __iomem *)ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram));
 
 	/* Fill global PRAM */
 
@@ -2768,7 +2774,7 @@
 	}
 
 	ugeth->p_thread_data_tx =
-	    (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_thread_data_tx __iomem *) qe_muram_addr(ugeth->
 							thread_dat_tx_offset);
 	out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset);
 
@@ -2779,7 +2785,8 @@
 
 	/* iphoffset */
 	for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++)
-		ugeth->p_tx_glbl_pram->iphoffset[i] = ug_info->iphoffset[i];
+		out_8(&ugeth->p_tx_glbl_pram->iphoffset[i],
+				ug_info->iphoffset[i]);
 
 	/* SQPTR */
 	/* Size varies with number of Tx queues */
@@ -2797,7 +2804,7 @@
 	}
 
 	ugeth->p_send_q_mem_reg =
-	    (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_send_queue_mem_region __iomem *) qe_muram_addr(ugeth->
 			send_q_mem_reg_offset);
 	out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset);
 
@@ -2841,25 +2848,26 @@
 		}
 
 		ugeth->p_scheduler =
-		    (struct ucc_geth_scheduler *) qe_muram_addr(ugeth->
+		    (struct ucc_geth_scheduler __iomem *) 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(struct ucc_geth_scheduler));
+		memset_io((void __iomem *)ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler));
 
 		/* Set values in scheduler */
 		out_be32(&ugeth->p_scheduler->mblinterval,
 			 ug_info->mblinterval);
 		out_be16(&ugeth->p_scheduler->nortsrbytetime,
 			 ug_info->nortsrbytetime);
-		ugeth->p_scheduler->fracsiz = ug_info->fracsiz;
-		ugeth->p_scheduler->strictpriorityq = ug_info->strictpriorityq;
-		ugeth->p_scheduler->txasap = ug_info->txasap;
-		ugeth->p_scheduler->extrabw = ug_info->extrabw;
+		out_8(&ugeth->p_scheduler->fracsiz, ug_info->fracsiz);
+		out_8(&ugeth->p_scheduler->strictpriorityq,
+				ug_info->strictpriorityq);
+		out_8(&ugeth->p_scheduler->txasap, ug_info->txasap);
+		out_8(&ugeth->p_scheduler->extrabw, ug_info->extrabw);
 		for (i = 0; i < NUM_TX_QUEUES; i++)
-			ugeth->p_scheduler->weightfactor[i] =
-			    ug_info->weightfactor[i];
+			out_8(&ugeth->p_scheduler->weightfactor[i],
+			    ug_info->weightfactor[i]);
 
 		/* Set pointers to cpucount registers in scheduler */
 		ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0);
@@ -2890,10 +2898,10 @@
 			return -ENOMEM;
 		}
 		ugeth->p_tx_fw_statistics_pram =
-		    (struct ucc_geth_tx_firmware_statistics_pram *)
+		    (struct ucc_geth_tx_firmware_statistics_pram __iomem *)
 		    qe_muram_addr(ugeth->tx_fw_statistics_pram_offset);
 		/* Zero out p_tx_fw_statistics_pram */
-		memset(ugeth->p_tx_fw_statistics_pram,
+		memset_io((void __iomem *)ugeth->p_tx_fw_statistics_pram,
 		       0, sizeof(struct ucc_geth_tx_firmware_statistics_pram));
 	}
 
@@ -2930,10 +2938,10 @@
 		return -ENOMEM;
 	}
 	ugeth->p_rx_glbl_pram =
-	    (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_rx_global_pram __iomem *) qe_muram_addr(ugeth->
 							rx_glbl_pram_offset);
 	/* Zero out p_rx_glbl_pram */
-	memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram));
+	memset_io((void __iomem *)ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram));
 
 	/* Fill global PRAM */
 
@@ -2953,7 +2961,7 @@
 	}
 
 	ugeth->p_thread_data_rx =
-	    (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_thread_data_rx __iomem *) qe_muram_addr(ugeth->
 							thread_dat_rx_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset);
 
@@ -2976,10 +2984,10 @@
 			return -ENOMEM;
 		}
 		ugeth->p_rx_fw_statistics_pram =
-		    (struct ucc_geth_rx_firmware_statistics_pram *)
+		    (struct ucc_geth_rx_firmware_statistics_pram __iomem *)
 		    qe_muram_addr(ugeth->rx_fw_statistics_pram_offset);
 		/* Zero out p_rx_fw_statistics_pram */
-		memset(ugeth->p_rx_fw_statistics_pram, 0,
+		memset_io((void __iomem *)ugeth->p_rx_fw_statistics_pram, 0,
 		       sizeof(struct ucc_geth_rx_firmware_statistics_pram));
 	}
 
@@ -3000,7 +3008,7 @@
 	}
 
 	ugeth->p_rx_irq_coalescing_tbl =
-	    (struct ucc_geth_rx_interrupt_coalescing_table *)
+	    (struct ucc_geth_rx_interrupt_coalescing_table __iomem *)
 	    qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr,
 		 ugeth->rx_irq_coalescing_tbl_offset);
@@ -3069,11 +3077,11 @@
 	}
 
 	ugeth->p_rx_bd_qs_tbl =
-	    (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_rx_bd_queues_entry __iomem *) 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,
+	memset_io((void __iomem *)ugeth->p_rx_bd_qs_tbl,
 	       0,
 	       ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) +
 				       sizeof(struct ucc_geth_rx_prefetched_bds)));
@@ -3133,7 +3141,7 @@
 		&ugeth->p_rx_glbl_pram->remoder);
 
 	/* function code register */
-	ugeth->p_rx_glbl_pram->rstate = function_code;
+	out_8(&ugeth->p_rx_glbl_pram->rstate, function_code);
 
 	/* initialize extended filtering */
 	if (ug_info->rxExtendedFiltering) {
@@ -3160,7 +3168,7 @@
 		}
 
 		ugeth->p_exf_glbl_param =
-		    (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth->
+		    (struct ucc_geth_exf_global_pram __iomem *) qe_muram_addr(ugeth->
 				 exf_glbl_param_offset);
 		out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam,
 			 ugeth->exf_glbl_param_offset);
@@ -3175,7 +3183,7 @@
 			ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j);
 
 		p_82xx_addr_filt =
-		    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
+		    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->
 		    p_rx_glbl_pram->addressfiltering;
 
 		ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth,
@@ -3307,17 +3315,21 @@
 		return -ENOMEM;
 	}
 	p_init_enet_pram =
-	    (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset);
+	    (struct ucc_geth_init_pram __iomem *) 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;
-	p_init_enet_pram->resinit2 = ugeth->p_init_enet_param_shadow->resinit2;
-	p_init_enet_pram->resinit3 = ugeth->p_init_enet_param_shadow->resinit3;
-	p_init_enet_pram->resinit4 = ugeth->p_init_enet_param_shadow->resinit4;
+	out_8(&p_init_enet_pram->resinit1,
+			ugeth->p_init_enet_param_shadow->resinit1);
+	out_8(&p_init_enet_pram->resinit2,
+			ugeth->p_init_enet_param_shadow->resinit2);
+	out_8(&p_init_enet_pram->resinit3,
+			ugeth->p_init_enet_param_shadow->resinit3);
+	out_8(&p_init_enet_pram->resinit4,
+			ugeth->p_init_enet_param_shadow->resinit4);
 	out_be16(&p_init_enet_pram->resinit5,
 		 ugeth->p_init_enet_param_shadow->resinit5);
-	p_init_enet_pram->largestexternallookupkeysize =
-	    ugeth->p_init_enet_param_shadow->largestexternallookupkeysize;
+	out_8(&p_init_enet_pram->largestexternallookupkeysize,
+	    ugeth->p_init_enet_param_shadow->largestexternallookupkeysize);
 	out_be32(&p_init_enet_pram->rgftgfrxglobal,
 		 ugeth->p_init_enet_param_shadow->rgftgfrxglobal);
 	for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++)
@@ -3371,7 +3383,7 @@
 #ifdef CONFIG_UGETH_TX_ON_DEMAND
 	struct ucc_fast_private *uccf;
 #endif
-	u8 *bd;			/* BD pointer */
+	u8 __iomem *bd;			/* BD pointer */
 	u32 bd_status;
 	u8 txQ = 0;
 
@@ -3383,7 +3395,7 @@
 
 	/* Start from the next BD that should be filled */
 	bd = ugeth->txBd[txQ];
-	bd_status = in_be32((u32 *)bd);
+	bd_status = in_be32((u32 __iomem *)bd);
 	/* Save the skb pointer so we can free it later */
 	ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb;
 
@@ -3393,7 +3405,7 @@
 	     1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
 
 	/* set up the buffer descriptor */
-	out_be32(&((struct qe_bd *)bd)->buf,
+	out_be32(&((struct qe_bd __iomem *)bd)->buf,
 		      dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE));
 
 	/* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
@@ -3401,7 +3413,7 @@
 	bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len;
 
 	/* set bd status and length */
-	out_be32((u32 *)bd, bd_status);
+	out_be32((u32 __iomem *)bd, bd_status);
 
 	dev->trans_start = jiffies;
 
@@ -3441,7 +3453,7 @@
 static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
 {
 	struct sk_buff *skb;
-	u8 *bd;
+	u8 __iomem *bd;
 	u16 length, howmany = 0;
 	u32 bd_status;
 	u8 *bdBuffer;
@@ -3454,11 +3466,11 @@
 	/* collect received buffers */
 	bd = ugeth->rxBd[rxQ];
 
-	bd_status = in_be32((u32 *)bd);
+	bd_status = in_be32((u32 __iomem *)bd);
 
 	/* while there are received buffers and BD is full (~R_E) */
 	while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) {
-		bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf);
+		bdBuffer = (u8 *) in_be32(&((struct qe_bd __iomem *)bd)->buf);
 		length = (u16) ((bd_status & BD_LENGTH_MASK) - 4);
 		skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]];
 
@@ -3516,7 +3528,7 @@
 		else
 			bd += sizeof(struct qe_bd);
 
-		bd_status = in_be32((u32 *)bd);
+		bd_status = in_be32((u32 __iomem *)bd);
 	}
 
 	ugeth->rxBd[rxQ] = bd;
@@ -3527,11 +3539,11 @@
 {
 	/* Start from the next BD that should be filled */
 	struct ucc_geth_private *ugeth = netdev_priv(dev);
-	u8 *bd;			/* BD pointer */
+	u8 __iomem *bd;		/* BD pointer */
 	u32 bd_status;
 
 	bd = ugeth->confBd[txQ];
-	bd_status = in_be32((u32 *)bd);
+	bd_status = in_be32((u32 __iomem *)bd);
 
 	/* Normal processing. */
 	while ((bd_status & T_R) == 0) {
@@ -3561,7 +3573,7 @@
 			bd += sizeof(struct qe_bd);
 		else
 			bd = ugeth->p_tx_bd_ring[txQ];
-		bd_status = in_be32((u32 *)bd);
+		bd_status = in_be32((u32 __iomem *)bd);
 	}
 	ugeth->confBd[txQ] = bd;
 	return 0;
@@ -3910,7 +3922,7 @@
 			return -EINVAL;
 		}
 	} else {
-		prop = of_get_property(np, "rx-clock", NULL);
+		prop = of_get_property(np, "tx-clock", NULL);
 		if (!prop) {
 			printk(KERN_ERR
 				"ucc_geth: mising tx-clock-name property\n");
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 9f8b758..abc0e22 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -700,8 +700,8 @@
 	u32 iaddr_l;		/* individual address filter, low */
 	u32 gaddr_h;		/* group address filter, high */
 	u32 gaddr_l;		/* group address filter, low */
-	struct ucc_geth_82xx_enet_address taddr;
-	struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS];
+	struct ucc_geth_82xx_enet_address __iomem taddr;
+	struct ucc_geth_82xx_enet_address __iomem paddr[NUM_OF_PADDRS];
 	u8 res0[0x40 - 0x38];
 } __attribute__ ((packed));
 
@@ -1186,40 +1186,40 @@
 	struct ucc_fast_private *uccf;
 	struct net_device *dev;
 	struct napi_struct napi;
-	struct ucc_geth *ug_regs;
+	struct ucc_geth __iomem *ug_regs;
 	struct ucc_geth_init_pram *p_init_enet_param_shadow;
-	struct ucc_geth_exf_global_pram *p_exf_glbl_param;
+	struct ucc_geth_exf_global_pram __iomem *p_exf_glbl_param;
 	u32 exf_glbl_param_offset;
-	struct ucc_geth_rx_global_pram *p_rx_glbl_pram;
+	struct ucc_geth_rx_global_pram __iomem *p_rx_glbl_pram;
 	u32 rx_glbl_pram_offset;
-	struct ucc_geth_tx_global_pram *p_tx_glbl_pram;
+	struct ucc_geth_tx_global_pram __iomem *p_tx_glbl_pram;
 	u32 tx_glbl_pram_offset;
-	struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg;
+	struct ucc_geth_send_queue_mem_region __iomem *p_send_q_mem_reg;
 	u32 send_q_mem_reg_offset;
-	struct ucc_geth_thread_data_tx *p_thread_data_tx;
+	struct ucc_geth_thread_data_tx __iomem *p_thread_data_tx;
 	u32 thread_dat_tx_offset;
-	struct ucc_geth_thread_data_rx *p_thread_data_rx;
+	struct ucc_geth_thread_data_rx __iomem *p_thread_data_rx;
 	u32 thread_dat_rx_offset;
-	struct ucc_geth_scheduler *p_scheduler;
+	struct ucc_geth_scheduler __iomem *p_scheduler;
 	u32 scheduler_offset;
-	struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
+	struct ucc_geth_tx_firmware_statistics_pram __iomem *p_tx_fw_statistics_pram;
 	u32 tx_fw_statistics_pram_offset;
-	struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
+	struct ucc_geth_rx_firmware_statistics_pram __iomem *p_rx_fw_statistics_pram;
 	u32 rx_fw_statistics_pram_offset;
-	struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl;
+	struct ucc_geth_rx_interrupt_coalescing_table __iomem *p_rx_irq_coalescing_tbl;
 	u32 rx_irq_coalescing_tbl_offset;
-	struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl;
+	struct ucc_geth_rx_bd_queues_entry __iomem *p_rx_bd_qs_tbl;
 	u32 rx_bd_qs_tbl_offset;
-	u8 *p_tx_bd_ring[NUM_TX_QUEUES];
+	u8 __iomem *p_tx_bd_ring[NUM_TX_QUEUES];
 	u32 tx_bd_ring_offset[NUM_TX_QUEUES];
-	u8 *p_rx_bd_ring[NUM_RX_QUEUES];
+	u8 __iomem *p_rx_bd_ring[NUM_RX_QUEUES];
 	u32 rx_bd_ring_offset[NUM_RX_QUEUES];
-	u8 *confBd[NUM_TX_QUEUES];
-	u8 *txBd[NUM_TX_QUEUES];
-	u8 *rxBd[NUM_RX_QUEUES];
+	u8 __iomem *confBd[NUM_TX_QUEUES];
+	u8 __iomem *txBd[NUM_TX_QUEUES];
+	u8 __iomem *rxBd[NUM_RX_QUEUES];
 	int badFrame[NUM_RX_QUEUES];
 	u16 cpucount[NUM_TX_QUEUES];
-	volatile u16 *p_cpucount[NUM_TX_QUEUES];
+	u16 __iomem *p_cpucount[NUM_TX_QUEUES];
 	int indAddrRegUsed[NUM_OF_PADDRS];
 	u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS];	/* ethernet address */
 	u8 numGroupAddrInHash;
@@ -1251,4 +1251,12 @@
 	int oldlink;
 };
 
+void uec_set_ethtool_ops(struct net_device *netdev);
+int init_flow_control_params(u32 automatic_flow_control_mode,
+		int rx_flow_control_enable, int tx_flow_control_enable,
+		u16 pause_period, u16 extension_field,
+		u32 __iomem *upsmr_register, u32 __iomem *uempr_register,
+		u32 __iomem *maccfg1_register);
+
+
 #endif				/* __UCC_GETH_H__ */
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 3320003..5f176f2 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -108,12 +108,6 @@
 #define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings)
 #define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings)
 
-extern int init_flow_control_params(u32 automatic_flow_control_mode,
-		int rx_flow_control_enable,
-		int tx_flow_control_enable, u16 pause_period,
-		u16 extension_field, volatile u32 *upsmr_register,
-		volatile u32 *uempr_register, volatile u32 *maccfg1_register);
-
 static int
 uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 2af4907..9404747 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -104,7 +104,7 @@
 }
 
 /* Reset the MIIM registers, and wait for the bus to free */
-int uec_mdio_reset(struct mii_bus *bus)
+static int uec_mdio_reset(struct mii_bus *bus)
 {
 	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
 	unsigned int timeout = PHY_INIT_TIMEOUT;
@@ -240,7 +240,7 @@
 	return err;
 }
 
-int uec_mdio_remove(struct of_device *ofdev)
+static int uec_mdio_remove(struct of_device *ofdev)
 {
 	struct device *device = &ofdev->dev;
 	struct mii_bus *bus = dev_get_drvdata(device);
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 6f245cf..dc6f097 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1381,6 +1381,10 @@
 	USB_DEVICE (0x0411, 0x003d),
 	.driver_info =  (unsigned long) &ax8817x_info,
 }, {
+	// Buffalo LUA-U2-GT 10/100/1000
+	USB_DEVICE (0x0411, 0x006e),
+	.driver_info =  (unsigned long) &ax88178_info,
+}, {
 	// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
 	USB_DEVICE (0x6189, 0x182d),
 	.driver_info =  (unsigned long) &ax8817x_info,
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 8005dd1..d5140ae 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -150,11 +150,9 @@
 
 config HDLC_PPP
 	tristate "Synchronous Point-to-Point Protocol (PPP) support"
-	depends on HDLC && BROKEN
+	depends on HDLC
 	help
 	  Generic HDLC driver supporting PPP over WAN connections.
-	  This module is currently broken and will cause a kernel panic
-	  when a device configured in PPP mode is activated.
 
 	  It will be replaced by new PPP implementation in Linux 2.6.26.
 
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 45ddfc9..b0fce13 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -629,7 +629,7 @@
 	d->base_addr = chan->cosa->datareg;
 	d->irq = chan->cosa->irq;
 	d->dma = chan->cosa->dma;
-	d->priv = chan;
+	d->ml_priv = chan;
 	sppp_attach(&chan->pppdev);
 	if (register_netdev(d)) {
 		printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
@@ -650,7 +650,7 @@
 
 static int cosa_sppp_open(struct net_device *d)
 {
-	struct channel_data *chan = d->priv;
+	struct channel_data *chan = d->ml_priv;
 	int err;
 	unsigned long flags;
 
@@ -690,7 +690,7 @@
 
 static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct channel_data *chan = dev->priv;
+	struct channel_data *chan = dev->ml_priv;
 
 	netif_stop_queue(dev);
 
@@ -701,7 +701,7 @@
 
 static void cosa_sppp_timeout(struct net_device *dev)
 {
-	struct channel_data *chan = dev->priv;
+	struct channel_data *chan = dev->ml_priv;
 
 	if (test_bit(RXBIT, &chan->cosa->rxtx)) {
 		chan->stats.rx_errors++;
@@ -720,7 +720,7 @@
 
 static int cosa_sppp_close(struct net_device *d)
 {
-	struct channel_data *chan = d->priv;
+	struct channel_data *chan = d->ml_priv;
 	unsigned long flags;
 
 	netif_stop_queue(d);
@@ -800,7 +800,7 @@
 
 static struct net_device_stats *cosa_net_stats(struct net_device *dev)
 {
-	struct channel_data *chan = dev->priv;
+	struct channel_data *chan = dev->ml_priv;
 	return &chan->stats;
 }
 
@@ -1217,7 +1217,7 @@
 	int cmd)
 {
 	int rv;
-	struct channel_data *chan = dev->priv;
+	struct channel_data *chan = dev->ml_priv;
 	rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data);
 	if (rv == -ENOIOCTLCMD) {
 		return sppp_do_ioctl(dev, ifr, cmd);
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 10396d9..0030833 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -45,7 +45,7 @@
 	int (*old_ioctl)(struct net_device *, struct ifreq *, int);
 	int result;
 
-	dev->priv = &state(hdlc)->syncppp_ptr;
+	dev->ml_priv = &state(hdlc)->syncppp_ptr;
 	state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev;
 	state(hdlc)->pppdev.dev = dev;
 
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index 83dbc92..f3065d3 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -75,7 +75,7 @@
  
 static int hostess_open(struct net_device *d)
 {
-	struct sv11_device *sv11=d->priv;
+	struct sv11_device *sv11=d->ml_priv;
 	int err = -1;
 	
 	/*
@@ -128,7 +128,7 @@
 
 static int hostess_close(struct net_device *d)
 {
-	struct sv11_device *sv11=d->priv;
+	struct sv11_device *sv11=d->ml_priv;
 	/*
 	 *	Discard new frames
 	 */
@@ -159,14 +159,14 @@
 
 static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
 {
-	/* struct sv11_device *sv11=d->priv;
+	/* struct sv11_device *sv11=d->ml_priv;
 	   z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
 	return sppp_do_ioctl(d, ifr,cmd);
 }
 
 static struct net_device_stats *hostess_get_stats(struct net_device *d)
 {
-	struct sv11_device *sv11=d->priv;
+	struct sv11_device *sv11=d->ml_priv;
 	if(sv11)
 		return z8530_get_stats(&sv11->sync.chanA);
 	else
@@ -179,7 +179,7 @@
  
 static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d)
 {
-	struct sv11_device *sv11=d->priv;
+	struct sv11_device *sv11=d->ml_priv;
 	return z8530_queue_xmit(&sv11->sync.chanA, skb);
 }
 
@@ -325,6 +325,7 @@
 		/* 
 		 *	Initialise the PPP components
 		 */
+		d->ml_priv = sv;
 		sppp_attach(&sv->netdev);
 		
 		/*
@@ -333,7 +334,6 @@
 		
 		d->base_addr = iobase;
 		d->irq = irq;
-		d->priv = sv;
 		
 		if(register_netdev(d))
 		{
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index b5860b9..24fd613 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -459,6 +459,7 @@
 	list_for_each_safe(entry, tmp, &lapbeth_devices) {
 		lapbeth = list_entry(entry, struct lapbethdev, node);
 
+		dev_put(lapbeth->ethdev);
 		unregister_netdevice(lapbeth->axdev);
 	}
 	rtnl_unlock();
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 6635ece..62133ce 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -891,6 +891,7 @@
 
     /* Initialize the sppp layer */
     /* An ioctl can cause a subsequent detach for raw frame interface */
+    dev->ml_priv = sc;
     sc->if_type = LMC_PPP;
     sc->check = 0xBEAFCAFE;
     dev->base_addr = pci_resource_start(pdev, 0);
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 11276bf..44a89df 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -241,6 +241,7 @@
 		return NULL;
 
 	sv = d->priv;
+	d->ml_priv = sv;
 	sv->if_ptr = &sv->pppdev;
 	sv->pppdev.dev = d;
 	d->base_addr = iobase;
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 193e48f..5f3e849 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,6 +1,5 @@
 config IWLWIFI
-	bool
-	default n
+	tristate
 
 config IWLCORE
 	tristate "Intel Wireless Wifi Core"
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index d7beeff..ad4e7b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -666,7 +666,7 @@
 	rx_status.flag = 0;
 	rx_status.mactime = le64_to_cpu(rx_end->timestamp);
 	rx_status.freq =
-		ieee80211_frequency_to_channel(le16_to_cpu(rx_hdr->channel));
+		ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel));
 	rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
 				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 5baa000..8e3660e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -168,8 +168,8 @@
 	struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
 #endif
 	u32 dbg_fixed_rate;
-	struct iwl_priv *drv;
 #endif
+	struct iwl_priv *drv;
 };
 
 static void rs_rate_scale_perform(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 45cbd77..17847f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2905,7 +2905,7 @@
 
 	rx_status.mactime = le64_to_cpu(rx_start->timestamp);
 	rx_status.freq =
-		ieee80211_frequency_to_channel(le16_to_cpu(rx_start->channel));
+		ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel));
 	rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
 				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
 	rx_status.rate_idx =
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 04c2638..9196825 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -388,8 +388,15 @@
 
 	netif_start_queue(ndev);
 
-	/* Turn off carrier unless we know we have associated */
-	netif_carrier_off(ndev);
+	/* Turn off carrier if in STA or Ad-hoc mode. It will be turned on
+	 * once the firmware receives a trap of being associated
+	 * (GEN_OID_LINKSTATE). In other modes (AP or WDS or monitor) we
+	 * should just leave the carrier on as its expected the firmware
+	 * won't send us a trigger. */
+	if (priv->iw_mode == IW_MODE_INFRA || priv->iw_mode == IW_MODE_ADHOC)
+		netif_carrier_off(ndev);
+	else
+		netif_carrier_on(ndev);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index f51a50b..3a49c25 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1028,8 +1028,10 @@
 	 * Initialize the device.
 	 */
 	status = rt2x00dev->ops->lib->initialize(rt2x00dev);
-	if (status)
-		goto exit;
+	if (status) {
+		rt2x00queue_uninitialize(rt2x00dev);
+		return status;
+	}
 
 	__set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags);
 
@@ -1039,11 +1041,6 @@
 	rt2x00rfkill_register(rt2x00dev);
 
 	return 0;
-
-exit:
-	rt2x00lib_uninitialize(rt2x00dev);
-
-	return status;
 }
 
 int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 9e5d94e..c17078e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -314,13 +314,14 @@
 	if (status) {
 		ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
 		      pci_dev->irq, status);
-		return status;
+		goto exit;
 	}
 
 	return 0;
 
 exit:
-	rt2x00pci_uninitialize(rt2x00dev);
+	queue_for_each(rt2x00dev, queue)
+		rt2x00pci_free_queue_dma(rt2x00dev, queue);
 
 	return status;
 }
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index eaf23b9..edddbf3 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2361,6 +2361,7 @@
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct rt2x00_intf *intf = vif_to_intf(control->vif);
+	struct queue_entry_priv_pci_tx *priv_tx;
 	struct skb_frame_desc *skbdesc;
 	unsigned int beacon_base;
 	u32 reg;
@@ -2368,21 +2369,8 @@
 	if (unlikely(!intf->beacon))
 		return -ENOBUFS;
 
-	/*
-	 * We need to append the descriptor in front of the
-	 * beacon frame.
-	 */
-	if (skb_headroom(skb) < intf->beacon->queue->desc_size) {
-		if (pskb_expand_head(skb, intf->beacon->queue->desc_size,
-				     0, GFP_ATOMIC))
-			return -ENOMEM;
-	}
-
-	/*
-	 * Add the descriptor in front of the skb.
-	 */
-	skb_push(skb, intf->beacon->queue->desc_size);
-	memset(skb->data, 0, intf->beacon->queue->desc_size);
+	priv_tx = intf->beacon->priv_data;
+	memset(priv_tx->desc, 0, intf->beacon->queue->desc_size);
 
 	/*
 	 * Fill in skb descriptor
@@ -2390,9 +2378,9 @@
 	skbdesc = get_skb_frame_desc(skb);
 	memset(skbdesc, 0, sizeof(*skbdesc));
 	skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
-	skbdesc->data = skb->data + intf->beacon->queue->desc_size;
-	skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
-	skbdesc->desc = skb->data;
+	skbdesc->data = skb->data;
+	skbdesc->data_len = skb->len;
+	skbdesc->desc = priv_tx->desc;
 	skbdesc->desc_len = intf->beacon->queue->desc_size;
 	skbdesc->entry = intf->beacon;
 
@@ -2413,7 +2401,10 @@
 	rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 	beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
 	rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
-				      skb->data, skb->len);
+				      skbdesc->desc, skbdesc->desc_len);
+	rt2x00pci_register_multiwrite(rt2x00dev,
+				      beacon_base + skbdesc->desc_len,
+				      skbdesc->data, skbdesc->data_len);
 	rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON);
 
 	return 0;
@@ -2478,7 +2469,7 @@
 
 static const struct data_queue_desc rt61pci_queue_bcn = {
 	.entry_num		= 4 * BEACON_ENTRIES,
-	.data_size		= MGMT_FRAME_SIZE,
+	.data_size		= 0, /* No DMA required for beacons */
 	.desc_size		= TXINFO_SIZE,
 	.priv_size		= sizeof(struct queue_entry_priv_pci_tx),
 };
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 5dd23c9..883af89 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -2611,7 +2611,7 @@
 	 * We need a write method.
 	 */
 
-	if (tty->ops->write == NULL)
+	if (tty->ops->write == NULL || tty->ops->set_termios == NULL)
 		return -EOPNOTSUPP;
 
 	/*
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 03384a4..49ae970 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -908,9 +908,9 @@
 	     p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5],
 	     p->psa_call_code[6], p->psa_call_code[7]);
 #ifdef DEBUG_SHOW_UNUSED
-	printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n",
+	printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
 	       p->psa_reserved[0],
-	       p->psa_reserved[1], p->psa_reserved[2], p->psa_reserved[3]);
+	       p->psa_reserved[1]);
 #endif				/* DEBUG_SHOW_UNUSED */
 	printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
 	printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index baf7401..b584c0e 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -1074,11 +1074,9 @@
 	 p->psa_call_code[6],
 	 p->psa_call_code[7]);
 #ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n",
+  printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
 	 p->psa_reserved[0],
-	 p->psa_reserved[1],
-	 p->psa_reserved[2],
-	 p->psa_reserved[3]);
+	 p->psa_reserved[1]);
 #endif	/* DEBUG_SHOW_UNUSED */
   printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
   printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 5316074..12e24f0 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -889,9 +889,13 @@
 	}
 free_urb:
 	skb = (struct sk_buff *)urb->context;
-	zd_mac_tx_to_dev(skb, urb->status);
+	/*
+	 * grab 'usb' pointer before handing off the skb (since
+	 * it might be freed by zd_mac_tx_to_dev or mac80211)
+	 */
 	cb = (struct zd_tx_skb_control_block *)skb->cb;
 	usb = &zd_hw_mac(cb->hw)->chip.usb;
+	zd_mac_tx_to_dev(skb, urb->status);
 	free_tx_urb(usb, urb);
 	tx_dec_submitted_urbs(usb);
 	return;
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index efcbf4b..2450b3a3 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -27,7 +27,7 @@
 #include "buffer_sync.h"
 #include "oprof.h"
 
-DEFINE_PER_CPU_SHARED_ALIGNED(struct oprofile_cpu_buffer, cpu_buffer);
+DEFINE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
 
 static void wq_sync_buffer(struct work_struct *work);
 
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
index 1358817..c3e366b 100644
--- a/drivers/oprofile/cpu_buffer.h
+++ b/drivers/oprofile/cpu_buffer.h
@@ -46,7 +46,7 @@
 	unsigned long sample_invalid_eip;
 	int cpu;
 	struct delayed_work work;
-} ____cacheline_aligned;
+};
 
 DECLARE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer);
 
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 1fd8bb7..66c0fd2 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -49,7 +49,7 @@
 
 #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
 
-#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
+#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */
 
 #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
 
@@ -490,12 +490,12 @@
 
 #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
 {\
-	unsigned long start_time = jiffies;\
+	cycles_t start_time = get_cycles();\
 	while (1) {\
 		sts = op (iommu->reg + offset);\
 		if (cond)\
 			break;\
-		if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\
+		if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\
 			panic("DMAR hardware is malfunctioning\n");\
 		cpu_relax();\
 	}\
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 72f7476..9d6fc8e 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -19,8 +19,31 @@
 #include <linux/pci-acpi.h>
 #include "pci.h"
 
-static u32 ctrlset_buf[3] = {0, 0, 0};
-static u32 global_ctrlsets = 0;
+struct acpi_osc_data {
+	acpi_handle handle;
+	u32 ctrlset_buf[3];
+	u32 global_ctrlsets;
+	struct list_head sibiling;
+};
+static LIST_HEAD(acpi_osc_data_list);
+
+static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
+{
+	struct acpi_osc_data *data;
+
+	list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
+		if (data->handle == handle)
+			return data;
+	}
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return NULL;
+	INIT_LIST_HEAD(&data->sibiling);
+	data->handle = handle;
+	list_add_tail(&data->sibiling, &acpi_osc_data_list);
+	return data;
+}
+
 static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
 
 static acpi_status  
@@ -37,8 +60,27 @@
 	union acpi_object 	*out_obj;
 	u32			osc_dw0;
 	acpi_status *ret_status = (acpi_status *)retval;
+	struct acpi_osc_data *osc_data;
+	u32 flags = (unsigned long)context, temp;
+	acpi_handle tmp;
 
-	
+	status = acpi_get_handle(handle, "_OSC", &tmp);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	osc_data = acpi_get_osc_data(handle);
+	if (!osc_data) {
+		printk(KERN_ERR "acpi osc data array is full\n");
+		return AE_ERROR;
+	}
+
+	osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
+
+	/* do _OSC query for all possible controls */
+	temp = osc_data->ctrlset_buf[OSC_CONTROL_TYPE];
+	osc_data->ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+
 	/* Setting up input parameters */
 	input.count = 4;
 	input.pointer = in_params;
@@ -51,13 +93,11 @@
 	in_params[2].integer.value	= 3;
 	in_params[3].type		= ACPI_TYPE_BUFFER;
 	in_params[3].buffer.length 	= 12;
-	in_params[3].buffer.pointer 	= (u8 *)context;
+	in_params[3].buffer.pointer 	= (u8 *)osc_data->ctrlset_buf;
 
 	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
-	if (ACPI_FAILURE (status)) {
-		*ret_status = status;
-		return status;
-	}
+	if (ACPI_FAILURE(status))
+		goto out_nofree;
 	out_obj = output.pointer;
 
 	if (out_obj->type != ACPI_TYPE_BUFFER) {
@@ -76,7 +116,8 @@
 			printk(KERN_DEBUG "_OSC invalid revision\n"); 
 		if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
 			/* Update Global Control Set */
-			global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
+			osc_data->global_ctrlsets =
+				*((u32 *)(out_obj->buffer.pointer + 8));
 			status = AE_OK;
 			goto query_osc_out;
 		}
@@ -85,12 +126,21 @@
 	}
 
 	/* Update Global Control Set */
-	global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
+	osc_data->global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
 	status = AE_OK;
 
 query_osc_out:
 	kfree(output.pointer);
+out_nofree:
 	*ret_status = status;
+
+	osc_data->ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
+	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = temp;
+	if (ACPI_FAILURE(status)) {
+		/* no osc support at all */
+		osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
+	}
+
 	return status;
 }
 
@@ -165,28 +215,15 @@
  **/
 acpi_status __pci_osc_support_set(u32 flags, const char *hid)
 {
-	u32 temp;
-	acpi_status retval;
+	acpi_status retval = AE_NOT_FOUND;
 
 	if (!(flags & OSC_SUPPORT_MASKS)) {
 		return AE_TYPE;
 	}
-	ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
-
-	/* do _OSC query for all possible controls */
-	temp = ctrlset_buf[OSC_CONTROL_TYPE];
-	ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
-	ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
 	acpi_get_devices(hid,
 			acpi_query_osc,
-			ctrlset_buf,
+			(void *)(unsigned long)flags,
 			(void **) &retval );
-	ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
-	ctrlset_buf[OSC_CONTROL_TYPE] = temp;
-	if (ACPI_FAILURE(retval)) {
-		/* no osc support at all */
-		ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
-	}
 	return AE_OK;
 }
 
@@ -201,19 +238,31 @@
 {
 	acpi_status	status;
 	u32		ctrlset;
+	acpi_handle tmp;
+	struct acpi_osc_data *osc_data;
+
+	status = acpi_get_handle(handle, "_OSC", &tmp);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	osc_data = acpi_get_osc_data(handle);
+	if (!osc_data) {
+		printk(KERN_ERR "acpi osc data array is full\n");
+		return AE_ERROR;
+	}
 
 	ctrlset = (flags & OSC_CONTROL_MASKS);
 	if (!ctrlset) {
 		return AE_TYPE;
 	}
-	if (ctrlset_buf[OSC_SUPPORT_TYPE] && 
-	 	((global_ctrlsets & ctrlset) != ctrlset)) {
+	if (osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] &&
+		((osc_data->global_ctrlsets & ctrlset) != ctrlset)) {
 		return AE_SUPPORT;
 	}
-	ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
-	status = acpi_run_osc(handle, ctrlset_buf);
+	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
+	status = acpi_run_osc(handle, osc_data->ctrlset_buf);
 	if (ACPI_FAILURE (status)) {
-		ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
+		osc_data->ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
 	}
 	
 	return status;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4a55bf3..3706ce7 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -842,26 +842,10 @@
  * reading the dword at 0x100 which must either be 0 or a valid extended
  * capability header.
  */
-int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix)
+int pci_cfg_space_size_ext(struct pci_dev *dev)
 {
-	int pos;
 	u32 status;
 
-	if (!check_exp_pcix)
-		goto skip;
-
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-	if (!pos) {
-		pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
-		if (!pos)
-			goto fail;
-
-		pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
-		if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)))
-			goto fail;
-	}
-
- skip:
 	if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
 		goto fail;
 	if (status == 0xffffffff)
@@ -875,7 +859,24 @@
 
 int pci_cfg_space_size(struct pci_dev *dev)
 {
-	return pci_cfg_space_size_ext(dev, 1);
+	int pos;
+	u32 status;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (!pos) {
+		pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+		if (!pos)
+			goto fail;
+
+		pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
+		if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)))
+			goto fail;
+	}
+
+	return pci_cfg_space_size_ext(dev);
+
+ fail:
+	return PCI_CFG_SPACE_SIZE;
 }
 
 static void pci_release_bus_bridge_dev(struct device *dev)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index afd914e..f2d9c77 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1826,6 +1826,7 @@
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
 
 static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
 {
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 4fe7c58..886dac8 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -19,6 +19,7 @@
 int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
 void pnp_remove_card_device(struct pnp_dev *dev);
 
+struct pnp_option *pnp_build_option(int priority);
 struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
 struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
 						 int priority);
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 5d9301de..5695a79 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -424,7 +424,7 @@
 				start = simple_strtoul(buf, &buf, 0);
 				pnp_res = pnp_add_irq_resource(dev, start, 0);
 				if (pnp_res)
-					nirq++;
+					pnp_res->index = nirq++;
 				continue;
 			}
 			if (!strnicmp(buf, "dma", 3)) {
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index d049a22..ffdb12a 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -111,6 +111,113 @@
 		dev_info(&dev->dev, "SB audio device quirk - increased port range\n");
 }
 
+static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev)
+{
+	struct pnp_option *head = NULL;
+	struct pnp_option *prev = NULL;
+	struct pnp_option *res;
+
+	/*
+	 * Build a functional IRQ-less variant of each MPU option.
+	 */
+
+	for (res = dev->dependent; res; res = res->next) {
+		struct pnp_option *curr;
+		struct pnp_port *port;
+		struct pnp_port *copy;
+
+		port = res->port;
+		if (!port || !res->irq)
+			continue;
+
+		copy = pnp_alloc(sizeof *copy);
+		if (!copy)
+			break;
+
+		copy->min = port->min;
+		copy->max = port->max;
+		copy->align = port->align;
+		copy->size = port->size;
+		copy->flags = port->flags;
+
+		curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
+		if (!curr) {
+			kfree(copy);
+			break;
+		}
+		curr->port = copy;
+
+		if (prev)
+			prev->next = curr;
+		else
+			head = curr;
+		prev = curr;
+	}
+	if (head)
+		dev_info(&dev->dev, "adding IRQ-less MPU options\n");
+
+	return head;
+}
+
+static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
+{
+	struct pnp_option *res;
+	struct pnp_irq *irq;
+
+	/*
+	 * Distribute the independent IRQ over the dependent options
+	 */
+
+	res = dev->independent;
+	if (!res)
+		return;
+
+	irq = res->irq;
+	if (!irq || irq->next)
+		return;
+
+	res = dev->dependent;
+	if (!res)
+		return;
+
+	while (1) {
+		struct pnp_irq *copy;
+
+		copy = pnp_alloc(sizeof *copy);
+		if (!copy)
+			break;
+
+		memcpy(copy->map, irq->map, sizeof copy->map);
+		copy->flags = irq->flags;
+
+		copy->next = res->irq; /* Yes, this is NULL */
+		res->irq = copy;
+
+		if (!res->next)
+			break;
+		res = res->next;
+	}
+	kfree(irq);
+
+	res->next = quirk_isapnp_mpu_options(dev);
+
+	res = dev->independent;
+	res->irq = NULL;
+}
+
+static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)
+{
+	struct pnp_option *res;
+
+	res = dev->dependent;
+	if (!res)
+		return;
+
+	while (res->next)
+		res = res->next;
+
+	res->next = quirk_isapnp_mpu_options(dev);
+}
 
 #include <linux/pci.h>
 
@@ -205,6 +312,11 @@
 	{"CTL0043", quirk_sb16audio_resources},
 	{"CTL0044", quirk_sb16audio_resources},
 	{"CTL0045", quirk_sb16audio_resources},
+	/* Add IRQ-less MPU options */
+	{"ADS7151", quirk_ad1815_mpu_resources},
+	{"ADS7181", quirk_isapnp_mpu_resources},
+	{"AZT0002", quirk_isapnp_mpu_resources},
+	/* PnP resources that might overlap PCI BARs */
 	{"PNP0c01", quirk_system_pci_resources},
 	{"PNP0c02", quirk_system_pci_resources},
 	{""}
@@ -212,20 +324,16 @@
 
 void pnp_fixup_device(struct pnp_dev *dev)
 {
-	int i = 0;
-	void (*quirk)(struct pnp_dev *);
+	struct pnp_fixup *f;
 
-	while (*pnp_fixups[i].id) {
-		if (compare_pnp_id(dev->id, pnp_fixups[i].id)) {
-			quirk = pnp_fixups[i].quirk_function;
-
+	for (f = pnp_fixups; *f->id; f++) {
+		if (!compare_pnp_id(dev->id, f->id))
+			continue;
 #ifdef DEBUG
-			dev_dbg(&dev->dev, "calling ");
-			print_fn_descriptor_symbol("%s()\n",
-				(unsigned long) *quirk);
+		dev_dbg(&dev->dev, "%s: calling ", f->id);
+		print_fn_descriptor_symbol("%s\n",
+				(unsigned long) f->quirk_function);
 #endif
-			(*quirk)(dev);
-		}
-		i++;
+		f->quirk_function(dev);
 	}
 }
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 2041620..390b500 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -28,7 +28,7 @@
  * option registration
  */
 
-static struct pnp_option *pnp_build_option(int priority)
+struct pnp_option *pnp_build_option(int priority)
 {
 	struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));
 
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 3eba85e..95b076c 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -45,10 +45,10 @@
 	str[0] = 'A' + ((id >> 26) & 0x3f) - 1;
 	str[1] = 'A' + ((id >> 21) & 0x1f) - 1;
 	str[2] = 'A' + ((id >> 16) & 0x1f) - 1;
-	str[3] = hex_asc((id >> 12) & 0xf);
-	str[4] = hex_asc((id >>  8) & 0xf);
-	str[5] = hex_asc((id >>  4) & 0xf);
-	str[6] = hex_asc((id >>  0) & 0xf);
+	str[3] = hex_asc_hi(id >> 8);
+	str[4] = hex_asc_lo(id >> 8);
+	str[5] = hex_asc_hi(id);
+	str[6] = hex_asc_lo(id);
 	str[7] = '\0';
 }
 
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index a83a40b..0f0d27d 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -184,7 +184,7 @@
 static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
 {
 	u8 mon, day, dow, hrs, min, sec, yrs, cen;
-	unsigned int flags;
+	unsigned long flags;
 
 	/*
 	 * won't have to change this for a while
@@ -247,7 +247,7 @@
 static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
 {
 	unsigned int century;
-	unsigned int flags;
+	unsigned long flags;
 
 	spin_lock_irqsave(&ds1511_lock, flags);
 	rtc_disable_update();
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index ba795a4..9f996ec 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -51,7 +51,7 @@
  */
 void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
 {
-	register int days, month, year;
+	unsigned int days, month, year;
 
 	days = time / 86400;
 	time -= days * 86400;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 316bfaa..a3e0880 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -15,6 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/i2c.h>
@@ -803,6 +804,7 @@
 
 #ifdef CONFIG_RTC_DRV_M41T80_WDT
 	if (clientdata->features & M41T80_FEATURE_HT) {
+		save_client = client;
 		rc = misc_register(&wdt_dev);
 		if (rc)
 			goto exit;
@@ -811,7 +813,6 @@
 			misc_deregister(&wdt_dev);
 			goto exit;
 		}
-		save_client = client;
 	}
 #endif
 	return 0;
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index 29f47ba..a6fa1f2 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -227,7 +227,7 @@
 	/* This chip uses multiple addresses, use dummy devices for them */
 	for (i = 1; i < 8; ++i) {
 		s35390a->client[i] = i2c_new_dummy(client->adapter,
-					client->addr + i, "rtc-s35390a");
+					client->addr + i);
 		if (!s35390a->client[i]) {
 			dev_err(&client->dev, "Address %02x unavailable\n",
 						client->addr + i);
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 110699b..1f88e9e 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -616,7 +616,7 @@
 		goto err_badres;
 	}
 
-	rtc->regbase = (void __iomem *)rtc->res->start;
+	rtc->regbase = ioremap_nocache(rtc->res->start, rtc->regsize);
 	if (unlikely(!rtc->regbase)) {
 		ret = -EINVAL;
 		goto err_badmap;
@@ -626,7 +626,7 @@
 					   &sh_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
-		goto err_badmap;
+		goto err_unmap;
 	}
 
 	rtc->capabilities = RTC_DEF_CAPABILITIES;
@@ -653,7 +653,7 @@
 		dev_err(&pdev->dev,
 			"request period IRQ failed with %d, IRQ %d\n", ret,
 			rtc->periodic_irq);
-		goto err_badmap;
+		goto err_unmap;
 	}
 
 	ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
@@ -663,7 +663,7 @@
 			"request carry IRQ failed with %d, IRQ %d\n", ret,
 			rtc->carry_irq);
 		free_irq(rtc->periodic_irq, rtc);
-		goto err_badmap;
+		goto err_unmap;
 	}
 
 	ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
@@ -674,7 +674,7 @@
 			rtc->alarm_irq);
 		free_irq(rtc->carry_irq, rtc);
 		free_irq(rtc->periodic_irq, rtc);
-		goto err_badmap;
+		goto err_unmap;
 	}
 
 	tmp = readb(rtc->regbase + RCR1);
@@ -684,6 +684,8 @@
 
 	return 0;
 
+err_unmap:
+	iounmap(rtc->regbase);
 err_badmap:
 	release_resource(rtc->res);
 err_badres:
@@ -708,6 +710,8 @@
 
 	release_resource(rtc->res);
 
+	iounmap(rtc->regbase);
+
 	platform_set_drvdata(pdev, NULL);
 
 	kfree(rtc);
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index c1f2ade..5043150 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -965,8 +965,7 @@
  * Insert character into the screen at the current position with the
  * current color and highlight. This function does NOT do cursor movement.
  */
-static int
-tty3270_put_character(struct tty3270 *tp, char ch)
+static void tty3270_put_character(struct tty3270 *tp, char ch)
 {
 	struct tty3270_line *line;
 	struct tty3270_cell *cell;
@@ -986,7 +985,6 @@
 	cell->character = tp->view.ascebc[(unsigned int) ch];
 	cell->highlight = tp->highlight;
 	cell->f_color = tp->f_color;
-	return 1;
 }
 
 /*
@@ -1612,16 +1610,15 @@
 /*
  * Put single characters to the ttys character buffer
  */
-static void
-tty3270_put_char(struct tty_struct *tty, unsigned char ch)
+static int tty3270_put_char(struct tty_struct *tty, unsigned char ch)
 {
 	struct tty3270 *tp;
 
 	tp = tty->driver_data;
-	if (!tp)
-		return;
-	if (tp->char_count < TTY3270_CHAR_BUF_SIZE)
-		tp->char_buf[tp->char_count++] = ch;
+	if (!tp || tp->char_count >= TTY3270_CHAR_BUF_SIZE)
+		return 0;
+	tp->char_buf[tp->char_count++] = ch;
+	return 1;
 }
 
 /*
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 40ef948..9c21b8f 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -19,6 +19,7 @@
 
 #include <asm/cio.h>
 #include <asm/uaccess.h>
+#include <asm/cio.h>
 
 #include "blacklist.h"
 #include "cio.h"
@@ -43,164 +44,169 @@
  * Function: blacklist_range
  * (Un-)blacklist the devices from-to
  */
-static void
-blacklist_range (range_action action, unsigned int from, unsigned int to,
-		 unsigned int ssid)
+static int blacklist_range(range_action action, unsigned int from_ssid,
+			   unsigned int to_ssid, unsigned int from,
+			   unsigned int to, int msgtrigger)
 {
-	if (!to)
-		to = from;
-
-	if (from > to || to > __MAX_SUBCHANNEL || ssid > __MAX_SSID) {
-		printk (KERN_WARNING "cio: Invalid blacklist range "
-			"0.%x.%04x to 0.%x.%04x, skipping\n",
-			ssid, from, ssid, to);
-		return;
+	if ((from_ssid > to_ssid) || ((from_ssid == to_ssid) && (from > to))) {
+		if (msgtrigger)
+			printk(KERN_WARNING "cio: Invalid cio_ignore range "
+			       "0.%x.%04x-0.%x.%04x\n", from_ssid, from,
+			       to_ssid, to);
+		return 1;
 	}
-	for (; from <= to; from++) {
+
+	while ((from_ssid < to_ssid) || ((from_ssid == to_ssid) &&
+	       (from <= to))) {
 		if (action == add)
-			set_bit (from, bl_dev[ssid]);
+			set_bit(from, bl_dev[from_ssid]);
 		else
-			clear_bit (from, bl_dev[ssid]);
+			clear_bit(from, bl_dev[from_ssid]);
+		from++;
+		if (from > __MAX_SUBCHANNEL) {
+			from_ssid++;
+			from = 0;
+		}
 	}
-}
 
-/*
- * Function: blacklist_busid
- * Get devno/busid from given string.
- * Shamelessly grabbed from dasd_devmap.c.
- */
-static int
-blacklist_busid(char **str, int *id0, int *ssid, int *devno)
-{
-	int val, old_style;
-	char *sav;
-
-	sav = *str;
-
-	/* check for leading '0x' */
-	old_style = 0;
-	if ((*str)[0] == '0' && (*str)[1] == 'x') {
-		*str += 2;
-		old_style = 1;
-	}
-	if (!isxdigit((*str)[0]))	/* We require at least one hex digit */
-		goto confused;
-	val = simple_strtoul(*str, str, 16);
-	if (old_style || (*str)[0] != '.') {
-		*id0 = *ssid = 0;
-		if (val < 0 || val > 0xffff)
-			goto confused;
-		*devno = val;
-		if ((*str)[0] != ',' && (*str)[0] != '-' &&
-		    (*str)[0] != '\n' && (*str)[0] != '\0')
-			goto confused;
-		return 0;
-	}
-	/* New style x.y.z busid */
-	if (val < 0 || val > 0xff)
-		goto confused;
-	*id0 = val;
-	(*str)++;
-	if (!isxdigit((*str)[0]))	/* We require at least one hex digit */
-		goto confused;
-	val = simple_strtoul(*str, str, 16);
-	if (val < 0 || val > 0xff || (*str)++[0] != '.')
-		goto confused;
-	*ssid = val;
-	if (!isxdigit((*str)[0]))	/* We require at least one hex digit */
-		goto confused;
-	val = simple_strtoul(*str, str, 16);
-	if (val < 0 || val > 0xffff)
-		goto confused;
-	*devno = val;
-	if ((*str)[0] != ',' && (*str)[0] != '-' &&
-	    (*str)[0] != '\n' && (*str)[0] != '\0')
-		goto confused;
 	return 0;
-confused:
-	strsep(str, ",\n");
-	printk(KERN_WARNING "cio: Invalid cio_ignore parameter '%s'\n", sav);
-	return 1;
 }
 
-static int
-blacklist_parse_parameters (char *str, range_action action)
+static int pure_hex(char **cp, unsigned int *val, int min_digit,
+		    int max_digit, int max_val)
 {
-	int from, to, from_id0, to_id0, from_ssid, to_ssid;
+	int diff;
+	unsigned int value;
 
-	while (*str != 0 && *str != '\n') {
-		range_action ra = action;
-		while(*str == ',')
-			str++;
-		if (*str == '!') {
-			ra = !action;
-			++str;
-		}
+	diff = 0;
+	*val = 0;
 
-		/*
-		 * Since we have to parse the proc commands and the
-		 * kernel arguments we have to check four cases
-		 */
-		if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 ||
-		    strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) {
-			int j;
+	while (isxdigit(**cp) && (diff <= max_digit)) {
 
-			str += 3;
-			for (j=0; j <= __MAX_SSID; j++)
-				blacklist_range(ra, 0, __MAX_SUBCHANNEL, j);
-		} else {
-			int rc;
-
-			rc = blacklist_busid(&str, &from_id0,
-					     &from_ssid, &from);
-			if (rc)
-				continue;
-			to = from;
-			to_id0 = from_id0;
-			to_ssid = from_ssid;
-			if (*str == '-') {
-				str++;
-				rc = blacklist_busid(&str, &to_id0,
-						     &to_ssid, &to);
-				if (rc)
-					continue;
-			}
-			if (*str == '-') {
-				printk(KERN_WARNING "cio: invalid cio_ignore "
-					"parameter '%s'\n",
-					strsep(&str, ",\n"));
-				continue;
-			}
-			if ((from_id0 != to_id0) ||
-			    (from_ssid != to_ssid)) {
-				printk(KERN_WARNING "cio: invalid cio_ignore "
-				       "range %x.%x.%04x-%x.%x.%04x\n",
-				       from_id0, from_ssid, from,
-				       to_id0, to_ssid, to);
-				continue;
-			}
-			blacklist_range (ra, from, to, to_ssid);
-		}
+		if (isdigit(**cp))
+			value = **cp - '0';
+		else
+			value = tolower(**cp) - 'a' + 10;
+		*val = *val * 16 + value;
+		(*cp)++;
+		diff++;
 	}
-	return 1;
+
+	if ((diff < min_digit) || (diff > max_digit) || (*val > max_val))
+		return 1;
+
+	return 0;
 }
 
-/* Parsing the commandline for blacklist parameters, e.g. to blacklist
- * bus ids 0.0.1234, 0.0.1235 and 0.0.1236, you could use any of:
- * - cio_ignore=1234-1236
- * - cio_ignore=0x1234-0x1235,1236
- * - cio_ignore=0x1234,1235-1236
- * - cio_ignore=1236 cio_ignore=1234-0x1236
- * - cio_ignore=1234 cio_ignore=1236 cio_ignore=0x1235
- * - cio_ignore=0.0.1234-0.0.1236
- * - cio_ignore=0.0.1234,0x1235,1236
- * - ...
- */
+static int parse_busid(char *str, int *cssid, int *ssid, int *devno,
+		       int msgtrigger)
+{
+	char *str_work;
+	int val, rc, ret;
+
+	rc = 1;
+
+	if (*str == '\0')
+		goto out;
+
+	/* old style */
+	str_work = str;
+	val = simple_strtoul(str, &str_work, 16);
+
+	if (*str_work == '\0') {
+		if (val <= __MAX_SUBCHANNEL) {
+			*devno = val;
+			*ssid = 0;
+			*cssid = 0;
+			rc = 0;
+		}
+		goto out;
+	}
+
+	/* new style */
+	str_work = str;
+	ret = pure_hex(&str_work, cssid, 1, 2, __MAX_CSSID);
+	if (ret || (str_work[0] != '.'))
+		goto out;
+	str_work++;
+	ret = pure_hex(&str_work, ssid, 1, 1, __MAX_SSID);
+	if (ret || (str_work[0] != '.'))
+		goto out;
+	str_work++;
+	ret = pure_hex(&str_work, devno, 4, 4, __MAX_SUBCHANNEL);
+	if (ret || (str_work[0] != '\0'))
+		goto out;
+
+	rc = 0;
+out:
+	if (rc && msgtrigger)
+		printk(KERN_WARNING "cio: Invalid cio_ignore device '%s'\n",
+		       str);
+
+	return rc;
+}
+
+static int blacklist_parse_parameters(char *str, range_action action,
+				      int msgtrigger)
+{
+	int from_cssid, to_cssid, from_ssid, to_ssid, from, to;
+	int rc, totalrc;
+	char *parm;
+	range_action ra;
+
+	totalrc = 0;
+
+	while ((parm = strsep(&str, ","))) {
+		rc = 0;
+		ra = action;
+		if (*parm == '!') {
+			if (ra == add)
+				ra = free;
+			else
+				ra = add;
+			parm++;
+		}
+		if (strcmp(parm, "all") == 0) {
+			from_cssid = 0;
+			from_ssid = 0;
+			from = 0;
+			to_cssid = __MAX_CSSID;
+			to_ssid = __MAX_SSID;
+			to = __MAX_SUBCHANNEL;
+		} else {
+			rc = parse_busid(strsep(&parm, "-"), &from_cssid,
+					 &from_ssid, &from, msgtrigger);
+			if (!rc) {
+				if (parm != NULL)
+					rc = parse_busid(parm, &to_cssid,
+							 &to_ssid, &to,
+							 msgtrigger);
+				else {
+					to_cssid = from_cssid;
+					to_ssid = from_ssid;
+					to = from;
+				}
+			}
+		}
+		if (!rc) {
+			rc = blacklist_range(ra, from_ssid, to_ssid, from, to,
+					     msgtrigger);
+			if (rc)
+				totalrc = 1;
+		} else
+			totalrc = 1;
+	}
+
+	return totalrc;
+}
+
 static int __init
 blacklist_setup (char *str)
 {
 	CIO_MSG_EVENT(6, "Reading blacklist parameters\n");
-	return blacklist_parse_parameters (str, add);
+	if (blacklist_parse_parameters(str, add, 1))
+		return 0;
+	return 1;
 }
 
 __setup ("cio_ignore=", blacklist_setup);
@@ -224,27 +230,23 @@
  * Function: blacklist_parse_proc_parameters
  * parse the stuff which is piped to /proc/cio_ignore
  */
-static void
-blacklist_parse_proc_parameters (char *buf)
+static int blacklist_parse_proc_parameters(char *buf)
 {
-	if (strncmp (buf, "free ", 5) == 0) {
-		blacklist_parse_parameters (buf + 5, free);
-	} else if (strncmp (buf, "add ", 4) == 0) {
-		/* 
-		 * We don't need to check for known devices since
-		 * css_probe_device will handle this correctly. 
-		 */
-		blacklist_parse_parameters (buf + 4, add);
-	} else {
-		printk (KERN_WARNING "cio: cio_ignore: Parse error; \n"
-			KERN_WARNING "try using 'free all|<devno-range>,"
-				     "<devno-range>,...'\n"
-			KERN_WARNING "or 'add <devno-range>,"
-				     "<devno-range>,...'\n");
-		return;
-	}
+	int rc;
+	char *parm;
+
+	parm = strsep(&buf, " ");
+
+	if (strcmp("free", parm) == 0)
+		rc = blacklist_parse_parameters(buf, free, 0);
+	else if (strcmp("add", parm) == 0)
+		rc = blacklist_parse_parameters(buf, add, 0);
+	else
+		return 1;
 
 	css_schedule_reprobe();
+
+	return rc;
 }
 
 /* Iterator struct for all devices. */
@@ -328,6 +330,8 @@
 		 size_t user_len, loff_t *offset)
 {
 	char *buf;
+	size_t i;
+	ssize_t rc, ret;
 
 	if (*offset)
 		return -EINVAL;
@@ -336,16 +340,27 @@
 	buf = vmalloc (user_len + 1); /* maybe better use the stack? */
 	if (buf == NULL)
 		return -ENOMEM;
+	memset(buf, 0, user_len + 1);
+
 	if (strncpy_from_user (buf, user_buf, user_len) < 0) {
-		vfree (buf);
-		return -EFAULT;
+		rc = -EFAULT;
+		goto out_free;
 	}
-	buf[user_len] = '\0';
 
-	blacklist_parse_proc_parameters (buf);
+	i = user_len - 1;
+	while ((i >= 0) && (isspace(buf[i]) || (buf[i] == 0))) {
+		buf[i] = '\0';
+		i--;
+	}
+	ret = blacklist_parse_proc_parameters(buf);
+	if (ret)
+		rc = -EINVAL;
+	else
+		rc = user_len;
 
+out_free:
 	vfree (buf);
-	return user_len;
+	return rc;
 }
 
 static const struct seq_operations cio_ignore_proc_seq_ops = {
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 08a5781..82c6a2d 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -39,23 +39,6 @@
 debug_info_t *cio_debug_trace_id;
 debug_info_t *cio_debug_crw_id;
 
-int cio_show_msg;
-
-static int __init
-cio_setup (char *parm)
-{
-	if (!strcmp (parm, "yes"))
-		cio_show_msg = 1;
-	else if (!strcmp (parm, "no"))
-		cio_show_msg = 0;
-	else
-		printk(KERN_ERR "cio: cio_setup: "
-		       "invalid cio_msg parameter '%s'", parm);
-	return 1;
-}
-
-__setup ("cio_msg=", cio_setup);
-
 /*
  * Function: cio_debug_init
  * Initializes three debug logs for common I/O:
@@ -166,7 +149,7 @@
 
 	stsch (sch->schid, &sch->schib);
 
-	CIO_MSG_EVENT(0, "cio_start: 'not oper' status for "
+	CIO_MSG_EVENT(2, "cio_start: 'not oper' status for "
 		      "subchannel 0.%x.%04x!\n", sch->schid.ssid,
 		      sch->schid.sch_no);
 	sprintf(dbf_text, "no%s", sch->dev.bus_id);
@@ -567,10 +550,9 @@
 	 * ... just being curious we check for non I/O subchannels
 	 */
 	if (sch->st != 0) {
-		CIO_DEBUG(KERN_INFO, 0,
-			  "Subchannel 0.%x.%04x reports "
-			  "non-I/O subchannel type %04X\n",
-			  sch->schid.ssid, sch->schid.sch_no, sch->st);
+		CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports "
+			      "non-I/O subchannel type %04X\n",
+			      sch->schid.ssid, sch->schid.sch_no, sch->st);
 		/* We stop here for non-io subchannels. */
 		err = sch->st;
 		goto out;
@@ -588,7 +570,7 @@
 		 * This device must not be known to Linux. So we simply
 		 * say that there is no device and return ENODEV.
 		 */
-		CIO_MSG_EVENT(4, "Blacklisted device detected "
+		CIO_MSG_EVENT(6, "Blacklisted device detected "
 			      "at devno %04X, subchannel set %x\n",
 			      sch->schib.pmcw.dev, sch->schid.ssid);
 		err = -ENODEV;
@@ -601,12 +583,11 @@
 	sch->lpm = sch->schib.pmcw.pam & sch->opm;
 	sch->isc = 3;
 
-	CIO_DEBUG(KERN_INFO, 0,
-		  "Detected device %04x on subchannel 0.%x.%04X"
-		  " - PIM = %02X, PAM = %02X, POM = %02X\n",
-		  sch->schib.pmcw.dev, sch->schid.ssid,
-		  sch->schid.sch_no, sch->schib.pmcw.pim,
-		  sch->schib.pmcw.pam, sch->schib.pmcw.pom);
+	CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X "
+		      "- PIM = %02X, PAM = %02X, POM = %02X\n",
+		      sch->schib.pmcw.dev, sch->schid.ssid,
+		      sch->schid.sch_no, sch->schib.pmcw.pim,
+		      sch->schib.pmcw.pam, sch->schib.pmcw.pom);
 
 	/*
 	 * We now have to initially ...
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index 3c75412..6e933ae 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -118,6 +118,4 @@
 #define cio_get_console_priv() NULL
 #endif
 
-extern int cio_show_msg;
-
 #endif
diff --git a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h
index d7429ef..e64e827 100644
--- a/drivers/s390/cio/cio_debug.h
+++ b/drivers/s390/cio/cio_debug.h
@@ -31,10 +31,4 @@
 	}
 }
 
-#define CIO_DEBUG(printk_level, event_level, msg...) do {	\
-		if (cio_show_msg)				\
-			printk(printk_level "cio: " msg);	\
-		CIO_MSG_EVENT(event_level, msg);		\
-	} while (0)
-
 #endif
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 595e327..a769565 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -570,7 +570,7 @@
 {
 	int ret;
 
-	CIO_MSG_EVENT(2, "reprobe start\n");
+	CIO_MSG_EVENT(4, "reprobe start\n");
 
 	need_reprobe = 0;
 	/* Make sure initial subchannel scan is done. */
@@ -578,7 +578,7 @@
 		   atomic_read(&ccw_device_init_count) == 0);
 	ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
 
-	CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
+	CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
 		      need_reprobe);
 }
 
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index abfd601..e22813d 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -341,7 +341,7 @@
 		rc = device_schedule_callback(&cdev->dev,
 					      ccw_device_remove_orphan_cb);
 		if (rc)
-			CIO_MSG_EVENT(2, "Couldn't unregister orphan "
+			CIO_MSG_EVENT(0, "Couldn't unregister orphan "
 				      "0.%x.%04x\n",
 				      cdev->private->dev_id.ssid,
 				      cdev->private->dev_id.devno);
@@ -351,7 +351,7 @@
 	rc = device_schedule_callback(cdev->dev.parent,
 				      ccw_device_remove_sch_cb);
 	if (rc)
-		CIO_MSG_EVENT(2, "Couldn't unregister disconnected device "
+		CIO_MSG_EVENT(0, "Couldn't unregister disconnected device "
 			      "0.%x.%04x\n",
 			      cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno);
@@ -397,7 +397,7 @@
 	if (ret == 0)
 		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
 	else {
-		CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "
+		CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
 			      "device 0.%x.%04x\n",
 			      ret, cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno);
@@ -433,7 +433,7 @@
 	if (ret == 0)
 		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
 	else {
-		CIO_MSG_EVENT(2, "ccw_device_online returned %d, "
+		CIO_MSG_EVENT(0, "ccw_device_online returned %d, "
 			      "device 0.%x.%04x\n",
 			      ret, cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno);
@@ -451,7 +451,7 @@
 	if (ret == 0)
 		wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
 	else
-		CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "
+		CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
 			      "device 0.%x.%04x\n",
 			      ret, cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno);
@@ -803,7 +803,7 @@
 	other_sch = to_subchannel(get_device(cdev->dev.parent));
 	ret = device_move(&cdev->dev, &sch->dev);
 	if (ret) {
-		CIO_MSG_EVENT(2, "Moving disconnected device 0.%x.%04x failed "
+		CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
 			      "(ret=%d)!\n", cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno, ret);
 		put_device(&other_sch->dev);
@@ -933,7 +933,7 @@
 			ret = device_reprobe(&cdev->dev);
 			if (ret)
 				/* We can't do much here. */
-				CIO_MSG_EVENT(2, "device_reprobe() returned"
+				CIO_MSG_EVENT(0, "device_reprobe() returned"
 					      " %d for 0.%x.%04x\n", ret,
 					      cdev->private->dev_id.ssid,
 					      cdev->private->dev_id.devno);
@@ -1086,7 +1086,7 @@
 	rc = device_move(&cdev->dev, &sch->dev);
 	mutex_unlock(&sch->reg_mutex);
 	if (rc) {
-		CIO_MSG_EVENT(2, "Moving device 0.%x.%04x to subchannel "
+		CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
 			      "0.%x.%04x failed (ret=%d)!\n",
 			      cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno, sch->schid.ssid,
@@ -1446,8 +1446,7 @@
 			wait_event(cdev->private->wait_q,
 				   dev_fsm_final_state(cdev));
 		else
-			//FIXME: we can't fail!
-			CIO_MSG_EVENT(2, "ccw_device_offline returned %d, "
+			CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
 				      "device 0.%x.%04x\n",
 				      ret, cdev->private->dev_id.ssid,
 				      cdev->private->dev_id.devno);
@@ -1524,7 +1523,7 @@
 	spin_lock_irq(cdev->ccwlock);
 	switch (cdev->private->state) {
 	case DEV_STATE_DISCONNECTED:
-		CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n",
+		CIO_MSG_EVENT(4, "recovery: trigger 0.%x.%04x\n",
 			      cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno);
 		dev_fsm_event(cdev, DEV_EVENT_VERIFY);
@@ -1554,7 +1553,7 @@
 		}
 		spin_unlock_irq(&recovery_lock);
 	} else
-		CIO_MSG_EVENT(2, "recovery: end\n");
+		CIO_MSG_EVENT(4, "recovery: end\n");
 }
 
 static DECLARE_WORK(recovery_work, recovery_work_func);
@@ -1572,7 +1571,7 @@
 {
 	unsigned long flags;
 
-	CIO_MSG_EVENT(2, "recovery: schedule\n");
+	CIO_MSG_EVENT(4, "recovery: schedule\n");
 	spin_lock_irqsave(&recovery_lock, flags);
 	if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) {
 		recovery_phase = 0;
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 99403b0..e268d5a 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -322,10 +322,10 @@
 	same_dev = 0; /* Keep the compiler quiet... */
 	switch (state) {
 	case DEV_STATE_NOT_OPER:
-		CIO_DEBUG(KERN_WARNING, 2,
-			  "SenseID : unknown device %04x on subchannel "
-			  "0.%x.%04x\n", cdev->private->dev_id.devno,
-			  sch->schid.ssid, sch->schid.sch_no);
+		CIO_MSG_EVENT(2, "SenseID : unknown device %04x on "
+			      "subchannel 0.%x.%04x\n",
+			      cdev->private->dev_id.devno,
+			      sch->schid.ssid, sch->schid.sch_no);
 		break;
 	case DEV_STATE_OFFLINE:
 		if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
@@ -348,20 +348,19 @@
 			return;
 		}
 		/* Issue device info message. */
-		CIO_DEBUG(KERN_INFO, 2,
-			  "SenseID : device 0.%x.%04x reports: "
-			  "CU  Type/Mod = %04X/%02X, Dev Type/Mod = "
-			  "%04X/%02X\n",
-			  cdev->private->dev_id.ssid,
-			  cdev->private->dev_id.devno,
-			  cdev->id.cu_type, cdev->id.cu_model,
-			  cdev->id.dev_type, cdev->id.dev_model);
+		CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
+			      "CU  Type/Mod = %04X/%02X, Dev Type/Mod = "
+			      "%04X/%02X\n",
+			      cdev->private->dev_id.ssid,
+			      cdev->private->dev_id.devno,
+			      cdev->id.cu_type, cdev->id.cu_model,
+			      cdev->id.dev_type, cdev->id.dev_model);
 		break;
 	case DEV_STATE_BOXED:
-		CIO_DEBUG(KERN_WARNING, 2,
-			  "SenseID : boxed device %04x on subchannel "
-			  "0.%x.%04x\n", cdev->private->dev_id.devno,
-			  sch->schid.ssid, sch->schid.sch_no);
+		CIO_MSG_EVENT(0, "SenseID : boxed device %04x on "
+			      " subchannel 0.%x.%04x\n",
+			      cdev->private->dev_id.devno,
+			      sch->schid.ssid, sch->schid.sch_no);
 		break;
 	}
 	cdev->private->state = state;
@@ -443,9 +442,8 @@
 
 
 	if (state == DEV_STATE_BOXED)
-		CIO_DEBUG(KERN_WARNING, 2,
-			  "Boxed device %04x on subchannel %04x\n",
-			  cdev->private->dev_id.devno, sch->schid.sch_no);
+		CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
+			      cdev->private->dev_id.devno, sch->schid.sch_no);
 
 	if (cdev->private->flags.donotify) {
 		cdev->private->flags.donotify = 0;
@@ -900,7 +898,7 @@
 			/* Basic sense hasn't started. Try again. */
 			ccw_device_do_sense(cdev, irb);
 		else {
-			CIO_MSG_EVENT(2, "Huh? 0.%x.%04x: unsolicited "
+			CIO_MSG_EVENT(0, "0.%x.%04x: unsolicited "
 				      "interrupt during w4sense...\n",
 				      cdev->private->dev_id.ssid,
 				      cdev->private->dev_id.devno);
@@ -1169,8 +1167,10 @@
 static void
 ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event)
 {
-	CIO_MSG_EVENT(0, "dev_jumptable[%i][%i] == NULL\n",
-		      cdev->private->state, dev_event);
+	CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device "
+		      "0.%x.%04x\n", cdev->private->state, dev_event,
+		      cdev->private->dev_id.ssid,
+		      cdev->private->dev_id.devno);
 	BUG();
 }
 
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index dc4d87f..cba70205 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -214,7 +214,7 @@
 		 *     sense id information. So, for intervention required,
 		 *     we use the "whack it until it talks" strategy...
 		 */
-		CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel "
+		CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel "
 			      "0.%x.%04x reports cmd reject\n",
 			      cdev->private->dev_id.devno, sch->schid.ssid,
 			      sch->schid.sch_no);
@@ -239,7 +239,7 @@
 
 		lpm = to_io_private(sch)->orb.lpm;
 		if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0)
-			CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x "
+			CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x "
 				      "on subchannel 0.%x.%04x is "
 				      "'not operational'\n", lpm,
 				      cdev->private->dev_id.devno,
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index c52449a..ba55905 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -79,7 +79,7 @@
 			/* ret is 0, -EBUSY, -EACCES or -ENODEV */
 			if (ret != -EACCES)
 				return ret;
-			CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
+			CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel "
 				      "0.%x.%04x, lpm %02X, became 'not "
 				      "operational'\n",
 				      cdev->private->dev_id.devno,
@@ -159,7 +159,7 @@
 		u8 lpm;
 
 		lpm = to_io_private(sch)->orb.lpm;
-		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x,"
+		CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x,"
 			      " lpm %02X, became 'not operational'\n",
 			      cdev->private->dev_id.devno, sch->schid.ssid,
 			      sch->schid.sch_no, lpm);
@@ -275,7 +275,7 @@
 			return ret;
 	}
 	/* PGID command failed on this path. */
-	CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
+	CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel "
 		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
 		      cdev->private->dev_id.devno, sch->schid.ssid,
 		      sch->schid.sch_no, cdev->private->imask);
@@ -317,7 +317,7 @@
 			return ret;
 	}
 	/* nop command failed on this path. */
-	CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel "
+	CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel "
 		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
 		      cdev->private->dev_id.devno, sch->schid.ssid,
 		      sch->schid.sch_no, cdev->private->imask);
@@ -362,7 +362,7 @@
 		return -EAGAIN;
 	}
 	if (irb->scsw.cc == 3) {
-		CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x,"
+		CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x,"
 			      " lpm %02X, became 'not operational'\n",
 			      cdev->private->dev_id.devno, sch->schid.ssid,
 			      sch->schid.sch_no, cdev->private->imask);
@@ -391,7 +391,7 @@
 		return -ETIME;
 	}
 	if (irb->scsw.cc == 3) {
-		CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
+		CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x,"
 			      " lpm %02X, became 'not operational'\n",
 			      cdev->private->dev_id.devno, sch->schid.ssid,
 			      sch->schid.sch_no, cdev->private->imask);
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 4d4b542..5080f34 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -48,10 +48,11 @@
 	int ccode;
 	struct semaphore *sem;
 	unsigned int chain;
+	int ignore;
 
 	sem = (struct semaphore *)param;
 repeat:
-	down_interruptible(sem);
+	ignore = down_interruptible(sem);
 	chain = 0;
 	while (1) {
 		if (unlikely(chain > 1)) {
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 4fab0c2..b87037e 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -41,7 +41,7 @@
 #define BPP_DELAY 100
 
 static const unsigned  BPP_MAJOR = LP_MAJOR;
-static const char* dev_name = "bpp";
+static const char *bpp_dev_name = "bpp";
 
 /* When switching from compatibility to a mode where I can read, try
    the following mode first. */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 46d7e40..81ccbd7 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1679,6 +1679,7 @@
 config SCSI_MAC_ESP
 	tristate "Macintosh NCR53c9[46] SCSI"
 	depends on MAC && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is the NCR 53c9x SCSI controller found on most of the 68040
 	  based Macintoshes.
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index f5215fd..1dca177 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -3830,7 +3830,7 @@
 			iounmap(p);
 		}
 		if (!ok && setup_count == 0)
-			return 0;
+			return -ENODEV;
 
 		printk(KERN_INFO "aha152x: BIOS test: passed, ");
 #else
@@ -3909,14 +3909,14 @@
 #endif
 	}
 
-	return 1;
+	return 0;
 }
 
 static void __exit aha152x_exit(void)
 {
-	struct aha152x_hostdata *hd;
+	struct aha152x_hostdata *hd, *tmp;
 
-	list_for_each_entry(hd, &aha152x_host_list, host_list) {
+	list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) {
 		struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
 
 		aha152x_release(shost);
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 0fb5bf4..8508816 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -1967,45 +1967,6 @@
 	return rcode;
 }
 
-
-/*
- * This routine returns information about the system.  This does not effect
- * any logic and if the info is wrong - it doesn't matter.
- */
-
-/* Get all the info we can not get from kernel services */
-static int adpt_system_info(void __user *buffer)
-{
-	sysInfo_S si;
-
-	memset(&si, 0, sizeof(si));
-
-	si.osType = OS_LINUX;
-	si.osMajorVersion = 0;
-	si.osMinorVersion = 0;
-	si.osRevision = 0;
-	si.busType = SI_PCI_BUS;
-	si.processorFamily = DPTI_sig.dsProcessorFamily;
-
-#if defined __i386__ 
-	adpt_i386_info(&si);
-#elif defined (__ia64__)
-	adpt_ia64_info(&si);
-#elif defined(__sparc__)
-	adpt_sparc_info(&si);
-#elif defined (__alpha__)
-	adpt_alpha_info(&si);
-#else
-	si.processorType = 0xff ;
-#endif
-	if(copy_to_user(buffer, &si, sizeof(si))){
-		printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
 #if defined __ia64__ 
 static void adpt_ia64_info(sysInfo_S* si)
 {
@@ -2016,7 +1977,6 @@
 }
 #endif
 
-
 #if defined __sparc__ 
 static void adpt_sparc_info(sysInfo_S* si)
 {
@@ -2026,7 +1986,6 @@
 	si->processorType = PROC_ULTRASPARC;
 }
 #endif
-
 #if defined __alpha__ 
 static void adpt_alpha_info(sysInfo_S* si)
 {
@@ -2038,7 +1997,6 @@
 #endif
 
 #if defined __i386__
-
 static void adpt_i386_info(sysInfo_S* si)
 {
 	// This is all the info we need for now
@@ -2059,9 +2017,45 @@
 		break;
 	}
 }
-
 #endif
 
+/*
+ * This routine returns information about the system.  This does not effect
+ * any logic and if the info is wrong - it doesn't matter.
+ */
+
+/* Get all the info we can not get from kernel services */
+static int adpt_system_info(void __user *buffer)
+{
+	sysInfo_S si;
+
+	memset(&si, 0, sizeof(si));
+
+	si.osType = OS_LINUX;
+	si.osMajorVersion = 0;
+	si.osMinorVersion = 0;
+	si.osRevision = 0;
+	si.busType = SI_PCI_BUS;
+	si.processorFamily = DPTI_sig.dsProcessorFamily;
+
+#if defined __i386__
+	adpt_i386_info(&si);
+#elif defined (__ia64__)
+	adpt_ia64_info(&si);
+#elif defined(__sparc__)
+	adpt_sparc_info(&si);
+#elif defined (__alpha__)
+	adpt_alpha_info(&si);
+#else
+	si.processorType = 0xff ;
+#endif
+	if (copy_to_user(buffer, &si, sizeof(si))){
+		printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
+		return -EFAULT;
+	}
+
+	return 0;
+}
 
 static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
 	      ulong arg)
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 924cd5a..337746d 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -316,19 +316,6 @@
 static void adpt_delay(int millisec);
 #endif
 
-#if defined __ia64__ 
-static void adpt_ia64_info(sysInfo_S* si);
-#endif
-#if defined __sparc__ 
-static void adpt_sparc_info(sysInfo_S* si);
-#endif
-#if defined __alpha__ 
-static void adpt_sparc_info(sysInfo_S* si);
-#endif
-#if defined __i386__
-static void adpt_i386_info(sysInfo_S* si);
-#endif
-
 #define PRINT_BUFFER_SIZE     512
 
 #define HBA_FLAGS_DBG_FLAGS_MASK         0xffff0000	// Mask for debug flags
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 8e2e964..46771d4 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -550,7 +550,6 @@
 #endif /* CONFIG_ISA */
 
 #ifdef CONFIG_PCI
-static bool gdth_pci_registered;
 
 static bool gdth_search_vortex(ushort device)
 {
@@ -3724,6 +3723,8 @@
 }
 
 #ifdef GDTH_STATISTICS
+static unchar	gdth_timer_running;
+
 static void gdth_timeout(ulong data)
 {
     ulong32 i;
@@ -3731,7 +3732,10 @@
     gdth_ha_str *ha;
     ulong flags;
 
-    BUG_ON(list_empty(&gdth_instances));
+    if(unlikely(list_empty(&gdth_instances))) {
+	    gdth_timer_running = 0;
+	    return;
+    }
 
     ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
     spin_lock_irqsave(&ha->smp_lock, flags);
@@ -3751,6 +3755,22 @@
     add_timer(&gdth_timer);
     spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
+
+static void gdth_timer_init(void)
+{
+	if (gdth_timer_running)
+		return;
+	gdth_timer_running = 1;
+	TRACE2(("gdth_detect(): Initializing timer !\n"));
+	gdth_timer.expires = jiffies + HZ;
+	gdth_timer.data = 0L;
+	gdth_timer.function = gdth_timeout;
+	add_timer(&gdth_timer);
+}
+#else
+static inline void gdth_timer_init(void)
+{
+}
 #endif
 
 static void __init internal_setup(char *str,int *ints)
@@ -4735,6 +4755,7 @@
 	if (error)
 		goto out_free_coal_stat;
 	list_add_tail(&ha->list, &gdth_instances);
+	gdth_timer_init();
 
 	scsi_scan_host(shp);
 
@@ -4865,6 +4886,7 @@
 	if (error)
 		goto out_free_coal_stat;
 	list_add_tail(&ha->list, &gdth_instances);
+	gdth_timer_init();
 
 	scsi_scan_host(shp);
 
@@ -5011,6 +5033,7 @@
 	list_add_tail(&ha->list, &gdth_instances);
 
 	pci_set_drvdata(ha->pdev, ha);
+	gdth_timer_init();
 
 	scsi_scan_host(shp);
 
@@ -5110,6 +5133,7 @@
 	/* initializations */
 	gdth_polling = TRUE;
 	gdth_clear_events();
+	init_timer(&gdth_timer);
 
 	/* As default we do not probe for EISA or ISA controllers */
 	if (probe_eisa_isa) {
@@ -5132,23 +5156,17 @@
 
 #ifdef CONFIG_PCI
 	/* scanning for PCI controllers */
-	if (pci_register_driver(&gdth_pci_driver) == 0)
-		gdth_pci_registered = true;
+	if (pci_register_driver(&gdth_pci_driver)) {
+		gdth_ha_str *ha;
+
+		list_for_each_entry(ha, &gdth_instances, list)
+			gdth_remove_one(ha);
+		return -ENODEV;
+	}
 #endif /* CONFIG_PCI */
 
 	TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
 
-	if (list_empty(&gdth_instances))
-		return -ENODEV;
-
-#ifdef GDTH_STATISTICS
-	TRACE2(("gdth_detect(): Initializing timer !\n"));
-	init_timer(&gdth_timer);
-	gdth_timer.expires = jiffies + HZ;
-	gdth_timer.data = 0L;
-	gdth_timer.function = gdth_timeout;
-	add_timer(&gdth_timer);
-#endif
 	major = register_chrdev(0,"gdth", &gdth_fops);
 	register_reboot_notifier(&gdth_notifier);
 	gdth_polling = FALSE;
@@ -5167,8 +5185,7 @@
 #endif
 
 #ifdef CONFIG_PCI
-	if (gdth_pci_registered)
-		pci_unregister_driver(&gdth_pci_driver);
+	pci_unregister_driver(&gdth_pci_driver);
 #endif
 
 	list_for_each_entry(ha, &gdth_instances, list)
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 010c1b9..b43bf1d 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -730,7 +730,9 @@
 				if (iscsi_recv_pdu(conn->cls_conn, hdr, data,
 						   datalen))
 					rc = ISCSI_ERR_CONN_FAILED;
-			}
+			} else
+				mod_timer(&conn->transport_timer,
+					  jiffies + conn->recv_timeout);
 			iscsi_free_mgmt_task(conn, mtask);
 			break;
 		default:
@@ -1453,19 +1455,20 @@
 {
 	struct iscsi_conn *conn = (struct iscsi_conn *)data;
 	struct iscsi_session *session = conn->session;
-	unsigned long timeout, next_timeout = 0, last_recv;
+	unsigned long recv_timeout, next_timeout = 0, last_recv;
 
 	spin_lock(&session->lock);
 	if (session->state != ISCSI_STATE_LOGGED_IN)
 		goto done;
 
-	timeout = conn->recv_timeout;
-	if (!timeout)
+	recv_timeout = conn->recv_timeout;
+	if (!recv_timeout)
 		goto done;
 
-	timeout *= HZ;
+	recv_timeout *= HZ;
 	last_recv = conn->last_recv;
-	if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ),
+	if (conn->ping_mtask &&
+	    time_before_eq(conn->last_ping + (conn->ping_timeout * HZ),
 			   jiffies)) {
 		iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
 				  "expired, last rx %lu, last ping %lu, "
@@ -1476,15 +1479,13 @@
 		return;
 	}
 
-	if (time_before_eq(last_recv + timeout, jiffies)) {
-		if (time_before_eq(conn->last_ping, last_recv)) {
-			/* send a ping to try to provoke some traffic */
-			debug_scsi("Sending nopout as ping on conn %p\n", conn);
-			iscsi_send_nopout(conn, NULL);
-		}
-		next_timeout = last_recv + timeout + (conn->ping_timeout * HZ);
+	if (time_before_eq(last_recv + recv_timeout, jiffies)) {
+		/* send a ping to try to provoke some traffic */
+		debug_scsi("Sending nopout as ping on conn %p\n", conn);
+		iscsi_send_nopout(conn, NULL);
+		next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
 	} else
-		next_timeout = last_recv + timeout;
+		next_timeout = last_recv + recv_timeout;
 
 	debug_scsi("Setting next tmo %lu\n", next_timeout);
 	mod_timer(&conn->transport_timer, next_timeout);
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index fa06093..51e2f29 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -2007,7 +2007,7 @@
 		nv->bus[bus].config_2.req_ack_active_negation = 1;
 		nv->bus[bus].config_2.data_line_active_negation = 1;
 		nv->bus[bus].selection_timeout = 250;
-		nv->bus[bus].max_queue_depth = 256;
+		nv->bus[bus].max_queue_depth = 32;
 
 		if (IS_ISP1040(ha)) {
 			nv->bus[bus].bus_reset_delay = 3;
@@ -2051,7 +2051,7 @@
 	status = qla1280_mailbox_command(ha, 0x0f, mb);
 
 	/* Save Tag queuing enable flag. */
-	flag = (BIT_0 << target) & mb[0];
+	flag = (BIT_0 << target);
 	if (nv->bus[bus].target[target].parameter.tag_queuing)
 		ha->bus_settings[bus].qtag_enables |= flag;
 
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 36acbcc..62e6eb1 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -976,11 +976,15 @@
 	depends on SERIAL_68328
 
 config SERIAL_COLDFIRE
-	bool "ColdFire serial support"
+	bool "ColdFire serial support (DEPRECATED)"
 	depends on COLDFIRE
 	help
 	  This driver supports the built-in serial ports of the Motorola ColdFire
 	  family of CPUs.
+	  This driver is deprecated because it supports only the old interface
+	  for serial drivers and features like magic keys are not working.
+	  Please switch to the new style driver because this driver will be
+	  removed soon.
 
 config SERIAL_MCF
 	bool "Coldfire serial support (new style driver)"
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 8a2f6a1..d6b4ead 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -65,9 +65,6 @@
 {
 	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
 	struct circ_buf *xmit = &uart->port.info->xmit;
-#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA)
-	unsigned short ier;
-#endif
 
 	while (!(UART_GET_LSR(uart) & TEMT))
 		cpu_relax();
@@ -82,12 +79,8 @@
 #ifdef CONFIG_BF54x
 	/* Clear TFI bit */
 	UART_PUT_LSR(uart, TFI);
-	UART_CLEAR_IER(uart, ETBEI);
-#else
-	ier = UART_GET_IER(uart);
-	ier &= ~ETBEI;
-	UART_PUT_IER(uart, ier);
 #endif
+	UART_CLEAR_IER(uart, ETBEI);
 #endif
 }
 
@@ -102,14 +95,7 @@
 	if (uart->tx_done)
 		bfin_serial_dma_tx_chars(uart);
 #else
-#ifdef CONFIG_BF54x
 	UART_SET_IER(uart, ETBEI);
-#else
-	unsigned short ier;
-	ier = UART_GET_IER(uart);
-	ier |= ETBEI;
-	UART_PUT_IER(uart, ier);
-#endif
 	bfin_serial_tx_chars(uart);
 #endif
 }
@@ -120,21 +106,10 @@
 static void bfin_serial_stop_rx(struct uart_port *port)
 {
 	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
-#ifdef	CONFIG_KGDB_UART
-	if (uart->port.line != CONFIG_KGDB_UART_PORT) {
+#ifdef CONFIG_KGDB_UART
+	if (uart->port.line != CONFIG_KGDB_UART_PORT)
 #endif
-#ifdef CONFIG_BF54x
 	UART_CLEAR_IER(uart, ERBFI);
-#else
-	unsigned short ier;
-
-	ier = UART_GET_IER(uart);
-	ier &= ~ERBFI;
-	UART_PUT_IER(uart, ier);
-#endif
-#ifdef	CONFIG_KGDB_UART
-	}
-#endif
 }
 
 /*
@@ -161,10 +136,7 @@
 		SSYNC();
 	}
 
-#ifndef CONFIG_BF54x
-	UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
-	SSYNC();
-#endif
+	UART_CLEAR_DLAB(uart);
 	UART_PUT_CHAR(uart, (unsigned char)chr);
 	SSYNC();
 }
@@ -183,10 +155,7 @@
 	while(!(UART_GET_LSR(uart) & DR)) {
 		SSYNC();
 	}
-#ifndef CONFIG_BF54x
-	UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
-	SSYNC();
-#endif
+	UART_CLEAR_DLAB(uart);
 	chr = UART_GET_CHAR(uart);
 	SSYNC();
 
@@ -208,9 +177,6 @@
 	struct tty_struct *tty = uart->port.info->tty;
 	unsigned int status, ch, flg;
 	static struct timeval anomaly_start = { .tv_sec = 0 };
-#ifdef CONFIG_KGDB_UART
-	struct pt_regs *regs = get_irq_regs();
-#endif
 
 	status = UART_GET_LSR(uart);
 	UART_CLEAR_LSR(uart);
@@ -220,6 +186,7 @@
 
 #ifdef CONFIG_KGDB_UART
 	if (uart->port.line == CONFIG_KGDB_UART_PORT) {
+		struct pt_regs *regs = get_irq_regs();
 		if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */
 			kgdb_breakkey_pressed(regs);
 			return;
@@ -391,7 +358,6 @@
 static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 {
 	struct circ_buf *xmit = &uart->port.info->xmit;
-	unsigned short ier;
 
 	uart->tx_done = 0;
 
@@ -429,13 +395,7 @@
 	set_dma_x_modify(uart->tx_dma_channel, 1);
 	enable_dma(uart->tx_dma_channel);
 
-#ifdef CONFIG_BF54x
 	UART_SET_IER(uart, ETBEI);
-#else
-	ier = UART_GET_IER(uart);
-	ier |= ETBEI;
-	UART_PUT_IER(uart, ier);
-#endif
 }
 
 static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
@@ -513,19 +473,12 @@
 {
 	struct bfin_serial_port *uart = dev_id;
 	struct circ_buf *xmit = &uart->port.info->xmit;
-	unsigned short ier;
 
 	spin_lock(&uart->port.lock);
 	if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
 		disable_dma(uart->tx_dma_channel);
 		clear_dma_irqstat(uart->tx_dma_channel);
-#ifdef CONFIG_BF54x
 		UART_CLEAR_IER(uart, ETBEI);
-#else
-		ier = UART_GET_IER(uart);
-		ier &= ~ETBEI;
-		UART_PUT_IER(uart, ier);
-#endif
 		xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1);
 		uart->port.icount.tx += uart->tx_count;
 
@@ -701,7 +654,6 @@
 # endif
 	}
 
-
 	if (request_irq
 	    (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED,
 	     "BFIN_UART_TX", uart)) {
@@ -710,11 +662,7 @@
 		return -EBUSY;
 	}
 #endif
-#ifdef CONFIG_BF54x
 	UART_SET_IER(uart, ERBFI);
-#else
-	UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
-#endif
 	return 0;
 }
 
@@ -810,26 +758,15 @@
 	UART_PUT_IER(uart, 0);
 #endif
 
-#ifndef CONFIG_BF54x
 	/* Set DLAB in LCR to Access DLL and DLH */
-	val = UART_GET_LCR(uart);
-	val |= DLAB;
-	UART_PUT_LCR(uart, val);
-	SSYNC();
-#endif
+	UART_SET_DLAB(uart);
 
 	UART_PUT_DLL(uart, quot & 0xFF);
-	SSYNC();
 	UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
 	SSYNC();
 
-#ifndef CONFIG_BF54x
 	/* Clear DLAB in LCR to Access THR RBR IER */
-	val = UART_GET_LCR(uart);
-	val &= ~DLAB;
-	UART_PUT_LCR(uart, val);
-	SSYNC();
-#endif
+	UART_CLEAR_DLAB(uart);
 
 	UART_PUT_LCR(uart, lcr);
 
@@ -992,8 +929,7 @@
 	status = UART_GET_IER(uart) & (ERBFI | ETBEI);
 	if (status == (ERBFI | ETBEI)) {
 		/* ok, the port was enabled */
-		unsigned short lcr, val;
-		unsigned short dlh, dll;
+		u16 lcr, dlh, dll;
 
 		lcr = UART_GET_LCR(uart);
 
@@ -1010,22 +946,14 @@
 			case 2:	*bits = 7; break;
 			case 3:	*bits = 8; break;
 		}
-#ifndef CONFIG_BF54x
 		/* Set DLAB in LCR to Access DLL and DLH */
-		val = UART_GET_LCR(uart);
-		val |= DLAB;
-		UART_PUT_LCR(uart, val);
-#endif
+		UART_SET_DLAB(uart);
 
 		dll = UART_GET_DLL(uart);
 		dlh = UART_GET_DLH(uart);
 
-#ifndef CONFIG_BF54x
 		/* Clear DLAB in LCR to Access THR RBR IER */
-		val = UART_GET_LCR(uart);
-		val &= ~DLAB;
-		UART_PUT_LCR(uart, val);
-#endif
+		UART_CLEAR_DLAB(uart);
 
 		*baud = get_sclk() / (16*(dll | dlh << 8));
 	}
@@ -1290,11 +1218,7 @@
 		request_irq(uart->port.irq, bfin_serial_rx_int,
 			IRQF_DISABLED, "BFIN_UART_RX", uart);
 		pr_info("Request irq for kgdb uart port\n");
-#ifdef CONFIG_BF54x
 		UART_SET_IER(uart, ERBFI);
-#else
-		UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
-#endif
 		SSYNC();
 		t.c_cflag = CS8|B57600;
 		t.c_iflag = 0;
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index f9fa237..3e0366e 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -3808,7 +3808,7 @@
 
 	shutdown(info);
 	rs_flush_buffer(tty);
-	tty_ldisc_flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 43af40d..56007cc 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -1,3 +1,4 @@
+#warning This driver is deprecated. Check Kconfig for details.
 /*
  * mcfserial.c -- serial driver for ColdFire internal UARTS.
  *
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 1e2b9d8..eab0327 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -556,7 +556,7 @@
 static void uart_flush_buffer(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port;
 	unsigned long flags;
 
 	/*
@@ -568,6 +568,7 @@
 		return;
 	}
 
+	port = state->port;
 	pr_debug("uart_flush_buffer(%d) called\n", tty->index);
 
 	spin_lock_irqsave(&port->lock, flags);
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 9691061..8fdafc2 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -42,14 +42,12 @@
 #include <linux/console.h>
 #include <linux/platform_device.h>
 #include <linux/serial_sci.h>
-
-#ifdef CONFIG_CPU_FREQ
 #include <linux/notifier.h>
 #include <linux/cpufreq.h>
-#endif
-
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#include <linux/clk.h>
 #include <linux/ctype.h>
+
+#ifdef CONFIG_SUPERH
 #include <asm/clock.h>
 #include <asm/sh_bios.h>
 #include <asm/kgdb.h>
@@ -80,7 +78,7 @@
 	struct timer_list	break_timer;
 	int			break_flag;
 
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#ifdef CONFIG_SUPERH
 	/* Port clock */
 	struct clk		*clk;
 #endif
@@ -365,21 +363,19 @@
 static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 {
 	unsigned int fcr_val = 0;
+	unsigned short data;
 
-	if (cflag & CRTSCTS) {
-		fcr_val |= SCFCR_MCE;
+	if (port->mapbase == 0xffe00000) {
+		data = ctrl_inw(PSCR);
+		data &= ~0x03cf;
+		if (cflag & CRTSCTS)
+			fcr_val |= SCFCR_MCE;
+		else
+			data |= 0x0340;
 
-		ctrl_outw(0x0000, PORT_PSCR);
-	} else {
-		unsigned short data;
-
-		data = ctrl_inw(PORT_PSCR);
-		data &= 0x033f;
-		data |= 0x0400;
-		ctrl_outw(data, PORT_PSCR);
-
-		ctrl_outw(ctrl_inw(SCSPTR0) & 0x17, SCSPTR0);
+		ctrl_outw(data, PSCR);
 	}
+	/* SCIF1 and SCIF2 should be setup by board code */
 
 	sci_out(port, SCFCR, fcr_val);
 }
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index fa8700a..eb84833 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -76,12 +76,13 @@
 # define SCSCR_INIT(port) 0x32	/* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7722)
-# define SCPDR0			0xA405013E	/* 16 bit SCIF0 PSDR */
-# define SCSPTR0		SCPDR0
+# define PADR			0xA4050120
+# define PSDR			0xA405013e
+# define PWDR			0xA4050166
+# define PSCR			0xA405011E
 # define SCIF_ORER		0x0001	/* overrun error bit */
 # define SCSCR_INIT(port)	0x0038	/* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
-# define PORT_PSCR		0xA405011E
 #elif defined(CONFIG_CPU_SUBTYPE_SH7366)
 # define SCPDR0			0xA405013E      /* 16 bit SCIF0 PSDR */
 # define SCSPTR0		SCPDR0
@@ -320,7 +321,7 @@
   unsigned int addr = port->mapbase + (offset);			\
   if ((size) == 8) {						\
     ctrl_outb(value, addr);					\
-  } else {							\
+  } else if ((size) == 16) {					\
     ctrl_outw(value, addr);					\
   }
 
@@ -451,7 +452,11 @@
 SCIF_FNS(SCLSR,				0,  0, 0x28, 16)
 #else
 SCIF_FNS(SCFDR,                      0x0e, 16, 0x1C, 16)
+#if defined(CONFIG_CPU_SUBTYPE_SH7722)
+SCIF_FNS(SCSPTR,                        0,  0, 0, 0)
+#else
 SCIF_FNS(SCSPTR,                        0,  0, 0x20, 16)
+#endif
 SCIF_FNS(SCLSR,                         0,  0, 0x24, 16)
 #endif
 #endif
@@ -593,13 +598,25 @@
 		return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
 	return 1;
 }
-#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || defined(CONFIG_CPU_SUBTYPE_SH7366)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7366)
 static inline int sci_rxd_in(struct uart_port *port)
 {
 	if (port->mapbase == 0xffe00000)
 		return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
 	return 1;
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+	if (port->mapbase == 0xffe00000)
+		return ctrl_inb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */
+	if (port->mapbase == 0xffe10000)
+		return ctrl_inb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */
+	if (port->mapbase == 0xffe20000)
+		return ctrl_inb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */
+
+	return 1;
+}
 #elif defined(CONFIG_CPU_SUBTYPE_SH7723)
 static inline int sci_rxd_in(struct uart_port *port)
 {
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index fae9e8f..66ec5d8 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -126,7 +126,6 @@
 config SPI_MPC83xx
 	tristate "Freescale MPC83xx/QUICC Engine SPI controller"
 	depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
-	select SPI_BITBANG
 	help
 	  This enables using the Freescale MPC83xx and QUICC Engine SPI
 	  controllers in master mode.
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 90729469..681d623 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -1,5 +1,5 @@
 /*
- * MPC52xx SPC in SPI mode driver.
+ * MPC52xx PSC in SPI mode driver.
  *
  * Maintainer: Dragos Carp
  *
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 654bb58..0c452c4 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1567,7 +1567,7 @@
 	int status = 0;
 
 	/* Enable the SSP clock */
-	clk_disable(ssp->clk);
+	clk_enable(ssp->clk);
 
 	/* Start the queue running */
 	status = start_queue(drv_data);
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 189f706..6832da6 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -49,6 +49,7 @@
 #define	SPMODE_LEN(x)		((x) << 20)
 #define	SPMODE_PM(x)		((x) << 16)
 #define	SPMODE_OP		(1 << 14)
+#define	SPMODE_CG(x)		((x) << 7)
 
 /*
  * Default for SPI Mode:
@@ -67,10 +68,6 @@
 
 /* SPI Controller driver's private data. */
 struct mpc83xx_spi {
-	/* bitbang has to be first */
-	struct spi_bitbang bitbang;
-	struct completion done;
-
 	struct mpc83xx_spi_reg __iomem *base;
 
 	/* rx & tx bufs from the spi_transfer */
@@ -82,7 +79,7 @@
 	u32(*get_tx) (struct mpc83xx_spi *);
 
 	unsigned int count;
-	u32 irq;
+	int irq;
 
 	unsigned nsecs;		/* (clock cycle time)/2 */
 
@@ -94,6 +91,25 @@
 
 	void (*activate_cs) (u8 cs, u8 polarity);
 	void (*deactivate_cs) (u8 cs, u8 polarity);
+
+	u8 busy;
+
+	struct workqueue_struct *workqueue;
+	struct work_struct work;
+
+	struct list_head queue;
+	spinlock_t lock;
+
+	struct completion done;
+};
+
+struct spi_mpc83xx_cs {
+	/* functions to deal with different sized buffers */
+	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
+	u32 (*get_tx) (struct mpc83xx_spi *);
+	u32 rx_shift;		/* RX data reg shift when in qe mode */
+	u32 tx_shift;		/* TX data reg shift when in qe mode */
+	u32 hw_mode;		/* Holds HW mode register settings */
 };
 
 static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val)
@@ -137,6 +153,7 @@
 {
 	struct mpc83xx_spi *mpc83xx_spi;
 	u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+	struct spi_mpc83xx_cs	*cs = spi->controller_state;
 
 	mpc83xx_spi = spi_master_get_devdata(spi->master);
 
@@ -147,50 +164,26 @@
 
 	if (value == BITBANG_CS_ACTIVE) {
 		u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
-		u32 len = spi->bits_per_word;
-		u8 pm;
 
-		if (len == 32)
-			len = 0;
-		else
-			len = len - 1;
+		mpc83xx_spi->rx_shift = cs->rx_shift;
+		mpc83xx_spi->tx_shift = cs->tx_shift;
+		mpc83xx_spi->get_rx = cs->get_rx;
+		mpc83xx_spi->get_tx = cs->get_tx;
 
-		/* mask out bits we are going to set */
-		regval &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
-				| SPMODE_LEN(0xF) | SPMODE_DIV16
-				| SPMODE_PM(0xF) | SPMODE_REV | SPMODE_LOOP);
+		if (cs->hw_mode != regval) {
+			unsigned long flags;
+			void *tmp_ptr = &mpc83xx_spi->base->mode;
 
-		if (spi->mode & SPI_CPHA)
-			regval |= SPMODE_CP_BEGIN_EDGECLK;
-		if (spi->mode & SPI_CPOL)
-			regval |= SPMODE_CI_INACTIVEHIGH;
-		if (!(spi->mode & SPI_LSB_FIRST))
-			regval |= SPMODE_REV;
-		if (spi->mode & SPI_LOOP)
-			regval |= SPMODE_LOOP;
-
-		regval |= SPMODE_LEN(len);
-
-		if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) {
-			pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1;
-			if (pm > 0x0f) {
-				dev_err(&spi->dev, "Requested speed is too "
-					"low: %d Hz. Will use %d Hz instead.\n",
-					spi->max_speed_hz,
-					mpc83xx_spi->spibrg / 1024);
-				pm = 0x0f;
-			}
-			regval |= SPMODE_PM(pm) | SPMODE_DIV16;
-		} else {
-			pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4);
-			if (pm)
-				pm--;
-			regval |= SPMODE_PM(pm);
+			regval = cs->hw_mode;
+			/* Turn off IRQs locally to minimize time that
+			 * SPI is disabled
+			 */
+			local_irq_save(flags);
+			/* Turn off SPI unit prior changing mode */
+			mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
+			mpc83xx_spi_write_reg(tmp_ptr, regval);
+			local_irq_restore(flags);
 		}
-
-		/* Turn off SPI unit prior changing mode */
-		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
-		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
 		if (mpc83xx_spi->activate_cs)
 			mpc83xx_spi->activate_cs(spi->chip_select, pol);
 	}
@@ -201,8 +194,9 @@
 {
 	struct mpc83xx_spi *mpc83xx_spi;
 	u32 regval;
-	u8 bits_per_word;
+	u8 bits_per_word, pm;
 	u32 hz;
+	struct spi_mpc83xx_cs	*cs = spi->controller_state;
 
 	mpc83xx_spi = spi_master_get_devdata(spi->master);
 
@@ -223,122 +217,106 @@
 	    || ((bits_per_word > 16) && (bits_per_word != 32)))
 		return -EINVAL;
 
-	mpc83xx_spi->rx_shift = 0;
-	mpc83xx_spi->tx_shift = 0;
+	if (!hz)
+		hz = spi->max_speed_hz;
+
+	cs->rx_shift = 0;
+	cs->tx_shift = 0;
 	if (bits_per_word <= 8) {
-		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
-		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
+		cs->get_rx = mpc83xx_spi_rx_buf_u8;
+		cs->get_tx = mpc83xx_spi_tx_buf_u8;
 		if (mpc83xx_spi->qe_mode) {
-			mpc83xx_spi->rx_shift = 16;
-			mpc83xx_spi->tx_shift = 24;
+			cs->rx_shift = 16;
+			cs->tx_shift = 24;
 		}
 	} else if (bits_per_word <= 16) {
-		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16;
-		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16;
+		cs->get_rx = mpc83xx_spi_rx_buf_u16;
+		cs->get_tx = mpc83xx_spi_tx_buf_u16;
 		if (mpc83xx_spi->qe_mode) {
-			mpc83xx_spi->rx_shift = 16;
-			mpc83xx_spi->tx_shift = 16;
+			cs->rx_shift = 16;
+			cs->tx_shift = 16;
 		}
 	} else if (bits_per_word <= 32) {
-		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32;
-		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32;
+		cs->get_rx = mpc83xx_spi_rx_buf_u32;
+		cs->get_tx = mpc83xx_spi_tx_buf_u32;
 	} else
 		return -EINVAL;
 
 	if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
-		mpc83xx_spi->tx_shift = 0;
+		cs->tx_shift = 0;
 		if (bits_per_word <= 8)
-			mpc83xx_spi->rx_shift = 8;
+			cs->rx_shift = 8;
 		else
-			mpc83xx_spi->rx_shift = 0;
+			cs->rx_shift = 0;
 	}
 
-	/* nsecs = (clock period)/2 */
-	if (!hz)
-		hz = spi->max_speed_hz;
-	mpc83xx_spi->nsecs = (1000000000 / 2) / hz;
-	if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000)
-		return -EINVAL;
+	mpc83xx_spi->rx_shift = cs->rx_shift;
+	mpc83xx_spi->tx_shift = cs->tx_shift;
+	mpc83xx_spi->get_rx = cs->get_rx;
+	mpc83xx_spi->get_tx = cs->get_tx;
 
 	if (bits_per_word == 32)
 		bits_per_word = 0;
 	else
 		bits_per_word = bits_per_word - 1;
 
-	regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
-
 	/* mask out bits we are going to set */
-	regval &= ~(SPMODE_LEN(0xF) | SPMODE_REV);
-	regval |= SPMODE_LEN(bits_per_word);
-	if (!(spi->mode & SPI_LSB_FIRST))
-		regval |= SPMODE_REV;
+	cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16
+				  | SPMODE_PM(0xF));
 
-	/* Turn off SPI unit prior changing mode */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+	cs->hw_mode |= SPMODE_LEN(bits_per_word);
 
-	return 0;
-}
-
-/* the spi->mode bits understood by this driver: */
-#define MODEBITS	(SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
-			| SPI_LSB_FIRST | SPI_LOOP)
-
-static int mpc83xx_spi_setup(struct spi_device *spi)
-{
-	struct spi_bitbang *bitbang;
-	struct mpc83xx_spi *mpc83xx_spi;
-	int retval;
-
-	if (spi->mode & ~MODEBITS) {
-		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
-			spi->mode & ~MODEBITS);
-		return -EINVAL;
+	if ((mpc83xx_spi->spibrg / hz) >= 64) {
+		pm = mpc83xx_spi->spibrg / (hz * 64) - 1;
+		if (pm > 0x0f) {
+			dev_err(&spi->dev, "Requested speed is too "
+				"low: %d Hz. Will use %d Hz instead.\n",
+				hz, mpc83xx_spi->spibrg / 1024);
+			pm = 0x0f;
+		}
+		cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16;
+	} else {
+		pm = mpc83xx_spi->spibrg / (hz * 4);
+		if (pm)
+			pm--;
+		cs->hw_mode |= SPMODE_PM(pm);
 	}
+	regval =  mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+	if (cs->hw_mode != regval) {
+		unsigned long flags;
+		void *tmp_ptr = &mpc83xx_spi->base->mode;
 
-	if (!spi->max_speed_hz)
-		return -EINVAL;
-
-	bitbang = spi_master_get_devdata(spi->master);
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
-
-	if (!spi->bits_per_word)
-		spi->bits_per_word = 8;
-
-	retval = mpc83xx_spi_setup_transfer(spi, NULL);
-	if (retval < 0)
-		return retval;
-
-	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
-		__func__, spi->mode & (SPI_CPOL | SPI_CPHA),
-		spi->bits_per_word, 2 * mpc83xx_spi->nsecs);
-
-	/* NOTE we _need_ to call chipselect() early, ideally with adapter
-	 * setup, unless the hardware defaults cooperate to avoid confusion
-	 * between normal (active low) and inverted chipselects.
-	 */
-
-	/* deselect chip (low or high) */
-	spin_lock(&bitbang->lock);
-	if (!bitbang->busy) {
-		bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
-		ndelay(mpc83xx_spi->nsecs);
+		regval = cs->hw_mode;
+		/* Turn off IRQs locally to minimize time
+		 * that SPI is disabled
+		 */
+		local_irq_save(flags);
+		/* Turn off SPI unit prior changing mode */
+		mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
+		mpc83xx_spi_write_reg(tmp_ptr, regval);
+		local_irq_restore(flags);
 	}
-	spin_unlock(&bitbang->lock);
-
 	return 0;
 }
 
 static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct mpc83xx_spi *mpc83xx_spi;
-	u32 word;
+	u32 word, len, bits_per_word;
 
 	mpc83xx_spi = spi_master_get_devdata(spi->master);
 
 	mpc83xx_spi->tx = t->tx_buf;
 	mpc83xx_spi->rx = t->rx_buf;
-	mpc83xx_spi->count = t->len;
+	bits_per_word = spi->bits_per_word;
+	if (t->bits_per_word)
+		bits_per_word = t->bits_per_word;
+	len = t->len;
+	if (bits_per_word > 8)
+		len /= 2;
+	if (bits_per_word > 16)
+		len /= 2;
+	mpc83xx_spi->count = len;
 	INIT_COMPLETION(mpc83xx_spi->done);
 
 	/* enable rx ints */
@@ -353,7 +331,147 @@
 	/* disable rx ints */
 	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
 
-	return t->len - mpc83xx_spi->count;
+	return mpc83xx_spi->count;
+}
+
+static void mpc83xx_spi_work(struct work_struct *work)
+{
+	struct mpc83xx_spi *mpc83xx_spi =
+		container_of(work, struct mpc83xx_spi, work);
+
+	spin_lock_irq(&mpc83xx_spi->lock);
+	mpc83xx_spi->busy = 1;
+	while (!list_empty(&mpc83xx_spi->queue)) {
+		struct spi_message *m;
+		struct spi_device *spi;
+		struct spi_transfer *t = NULL;
+		unsigned cs_change;
+		int status, nsecs = 50;
+
+		m = container_of(mpc83xx_spi->queue.next,
+				struct spi_message, queue);
+		list_del_init(&m->queue);
+		spin_unlock_irq(&mpc83xx_spi->lock);
+
+		spi = m->spi;
+		cs_change = 1;
+		status = 0;
+		list_for_each_entry(t, &m->transfers, transfer_list) {
+			if (t->bits_per_word || t->speed_hz) {
+				/* Don't allow changes if CS is active */
+				status = -EINVAL;
+
+				if (cs_change)
+					status = mpc83xx_spi_setup_transfer(spi, t);
+				if (status < 0)
+					break;
+			}
+
+			if (cs_change)
+				mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
+			cs_change = t->cs_change;
+			if (t->len)
+				status = mpc83xx_spi_bufs(spi, t);
+			if (status) {
+				status = -EMSGSIZE;
+				break;
+			}
+			m->actual_length += t->len;
+
+			if (t->delay_usecs)
+				udelay(t->delay_usecs);
+
+			if (cs_change) {
+				ndelay(nsecs);
+				mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+				ndelay(nsecs);
+			}
+		}
+
+		m->status = status;
+		m->complete(m->context);
+
+		if (status || !cs_change) {
+			ndelay(nsecs);
+			mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+		}
+
+		mpc83xx_spi_setup_transfer(spi, NULL);
+
+		spin_lock_irq(&mpc83xx_spi->lock);
+	}
+	mpc83xx_spi->busy = 0;
+	spin_unlock_irq(&mpc83xx_spi->lock);
+}
+
+/* the spi->mode bits understood by this driver: */
+#define MODEBITS	(SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
+			| SPI_LSB_FIRST | SPI_LOOP)
+
+static int mpc83xx_spi_setup(struct spi_device *spi)
+{
+	struct mpc83xx_spi *mpc83xx_spi;
+	int retval;
+	u32 hw_mode;
+	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+
+	if (spi->mode & ~MODEBITS) {
+		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
+			spi->mode & ~MODEBITS);
+		return -EINVAL;
+	}
+
+	if (!spi->max_speed_hz)
+		return -EINVAL;
+
+	if (!cs) {
+		cs = kzalloc(sizeof *cs, GFP_KERNEL);
+		if (!cs)
+			return -ENOMEM;
+		spi->controller_state = cs;
+	}
+	mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+	if (!spi->bits_per_word)
+		spi->bits_per_word = 8;
+
+	hw_mode = cs->hw_mode; /* Save orginal settings */
+	cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+	/* mask out bits we are going to set */
+	cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
+			 | SPMODE_REV | SPMODE_LOOP);
+
+	if (spi->mode & SPI_CPHA)
+		cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK;
+	if (spi->mode & SPI_CPOL)
+		cs->hw_mode |= SPMODE_CI_INACTIVEHIGH;
+	if (!(spi->mode & SPI_LSB_FIRST))
+		cs->hw_mode |= SPMODE_REV;
+	if (spi->mode & SPI_LOOP)
+		cs->hw_mode |= SPMODE_LOOP;
+
+	retval = mpc83xx_spi_setup_transfer(spi, NULL);
+	if (retval < 0) {
+		cs->hw_mode = hw_mode; /* Restore settings */
+		return retval;
+	}
+
+	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n",
+		__func__, spi->mode & (SPI_CPOL | SPI_CPHA),
+		spi->bits_per_word, spi->max_speed_hz);
+#if 0 /* Don't think this is needed */
+	/* NOTE we _need_ to call chipselect() early, ideally with adapter
+	 * setup, unless the hardware defaults cooperate to avoid confusion
+	 * between normal (active low) and inverted chipselects.
+	 */
+
+	/* deselect chip (low or high) */
+	spin_lock(&mpc83xx_spi->lock);
+	if (!mpc83xx_spi->busy)
+		mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+	spin_unlock(&mpc83xx_spi->lock);
+#endif
+	return 0;
 }
 
 irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
@@ -395,6 +513,28 @@
 
 	return ret;
 }
+static int mpc83xx_spi_transfer(struct spi_device *spi,
+				struct spi_message *m)
+{
+	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+	unsigned long flags;
+
+	m->actual_length = 0;
+	m->status = -EINPROGRESS;
+
+	spin_lock_irqsave(&mpc83xx_spi->lock, flags);
+	list_add_tail(&m->queue, &mpc83xx_spi->queue);
+	queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work);
+	spin_unlock_irqrestore(&mpc83xx_spi->lock, flags);
+
+	return 0;
+}
+
+
+static void mpc83xx_spi_cleanup(struct spi_device *spi)
+{
+	kfree(spi->controller_state);
+}
 
 static int __init mpc83xx_spi_probe(struct platform_device *dev)
 {
@@ -426,11 +566,11 @@
 		ret = -ENODEV;
 		goto free_master;
 	}
+	master->setup = mpc83xx_spi_setup;
+	master->transfer = mpc83xx_spi_transfer;
+	master->cleanup = mpc83xx_spi_cleanup;
+
 	mpc83xx_spi = spi_master_get_devdata(master);
-	mpc83xx_spi->bitbang.master = spi_master_get(master);
-	mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
-	mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer;
-	mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs;
 	mpc83xx_spi->activate_cs = pdata->activate_cs;
 	mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
 	mpc83xx_spi->qe_mode = pdata->qe_mode;
@@ -445,7 +585,6 @@
 		mpc83xx_spi->tx_shift = 24;
 	}
 
-	mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup;
 	init_completion(&mpc83xx_spi->done);
 
 	mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
@@ -483,11 +622,21 @@
 		regval |= SPMODE_OP;
 
 	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+	spin_lock_init(&mpc83xx_spi->lock);
+	init_completion(&mpc83xx_spi->done);
+	INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work);
+	INIT_LIST_HEAD(&mpc83xx_spi->queue);
 
-	ret = spi_bitbang_start(&mpc83xx_spi->bitbang);
-
-	if (ret != 0)
+	mpc83xx_spi->workqueue = create_singlethread_workqueue(
+		master->dev.parent->bus_id);
+	if (mpc83xx_spi->workqueue == NULL) {
+		ret = -EBUSY;
 		goto free_irq;
+	}
+
+	ret = spi_register_master(master);
+	if (ret < 0)
+		goto unreg_master;
 
 	printk(KERN_INFO
 	       "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
@@ -495,6 +644,8 @@
 
 	return ret;
 
+unreg_master:
+	destroy_workqueue(mpc83xx_spi->workqueue);
 free_irq:
 	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
 unmap_io:
@@ -515,10 +666,12 @@
 	master = platform_get_drvdata(dev);
 	mpc83xx_spi = spi_master_get_devdata(master);
 
-	spi_bitbang_stop(&mpc83xx_spi->bitbang);
+	flush_workqueue(mpc83xx_spi->workqueue);
+	destroy_workqueue(mpc83xx_spi->workqueue);
+	spi_unregister_master(master);
+
 	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
 	iounmap(mpc83xx_spi->base);
-	spi_master_put(mpc83xx_spi->bitbang.master);
 
 	return 0;
 }
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c
index f3430b3..5100fbb 100644
--- a/drivers/usb/c67x00/c67x00-ll-hpi.c
+++ b/drivers/usb/c67x00/c67x00-ll-hpi.c
@@ -23,6 +23,7 @@
 
 #include <asm/byteorder.h>
 #include <linux/io.h>
+#include <linux/jiffies.h>
 #include <linux/usb/c67x00.h>
 #include "c67x00.h"
 
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index cefe7f2..63c3404 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1248,6 +1248,9 @@
 	{ USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
 	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
 	},
+	{ USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */
+	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+	},
 
 	/* control interfaces with various AT-command sets */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index 99e5a68..fae55a3 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -156,6 +156,10 @@
 static struct attribute_group ep_dev_attr_grp = {
 	.attrs = ep_dev_attrs,
 };
+static struct attribute_group *ep_dev_groups[] = {
+	&ep_dev_attr_grp,
+	NULL
+};
 
 static int usb_endpoint_major_init(void)
 {
@@ -298,6 +302,7 @@
 
 	ep_dev->desc = &endpoint->desc;
 	ep_dev->udev = udev;
+	ep_dev->dev.groups = ep_dev_groups;
 	ep_dev->dev.devt = MKDEV(usb_endpoint_major, ep_dev->minor);
 	ep_dev->dev.class = ep_class->class;
 	ep_dev->dev.parent = parent;
@@ -309,9 +314,6 @@
 	retval = device_register(&ep_dev->dev);
 	if (retval)
 		goto error_chrdev;
-	retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
-	if (retval)
-		goto error_group;
 
 	/* create the symlink to the old-style "ep_XX" directory */
 	sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
@@ -322,8 +324,6 @@
 	return retval;
 
 error_link:
-	sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
-error_group:
 	device_unregister(&ep_dev->dev);
 	destroy_endpoint_class();
 	return retval;
@@ -348,7 +348,6 @@
 
 		sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
 		sysfs_remove_link(&ep_dev->dev.parent->kobj, name);
-		sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
 		device_unregister(&ep_dev->dev);
 		endpoint->ep_dev = NULL;
 		destroy_endpoint_class();
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 3e69266..fe47d14 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1607,6 +1607,7 @@
 		intf->dev.driver = NULL;
 		intf->dev.bus = &usb_bus_type;
 		intf->dev.type = &usb_if_device_type;
+		intf->dev.groups = usb_interface_groups;
 		intf->dev.dma_mask = dev->dev.dma_mask;
 		device_initialize(&intf->dev);
 		mark_quiesced(intf);
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 5b20a60..c783cb1 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -538,6 +538,46 @@
 	.attrs = dev_attrs,
 };
 
+/* When modifying this list, be sure to modify dev_string_attrs_are_visible()
+ * accordingly.
+ */
+static struct attribute *dev_string_attrs[] = {
+	&dev_attr_manufacturer.attr,
+	&dev_attr_product.attr,
+	&dev_attr_serial.attr,
+	NULL
+};
+
+static mode_t dev_string_attrs_are_visible(struct kobject *kobj,
+		struct attribute *a, int n)
+{
+	struct usb_device *udev = to_usb_device(
+			container_of(kobj, struct device, kobj));
+
+	if (a == &dev_attr_manufacturer.attr) {
+		if (udev->manufacturer == NULL)
+			return 0;
+	} else if (a == &dev_attr_product.attr) {
+		if (udev->product == NULL)
+			return 0;
+	} else if (a == &dev_attr_serial.attr) {
+		if (udev->serial == NULL)
+			return 0;
+	}
+	return a->mode;
+}
+
+static struct attribute_group dev_string_attr_grp = {
+	.attrs =	dev_string_attrs,
+	.is_visible =	dev_string_attrs_are_visible,
+};
+
+struct attribute_group *usb_device_groups[] = {
+	&dev_attr_grp,
+	&dev_string_attr_grp,
+	NULL
+};
+
 /* Binary descriptors */
 
 static ssize_t
@@ -591,10 +631,9 @@
 	struct device *dev = &udev->dev;
 	int retval;
 
-	retval = sysfs_create_group(&dev->kobj, &dev_attr_grp);
-	if (retval)
-		return retval;
-
+	/* Unforunately these attributes cannot be created before
+	 * the uevent is broadcast.
+	 */
 	retval = device_create_bin_file(dev, &dev_bin_attr_descriptors);
 	if (retval)
 		goto error;
@@ -607,21 +646,6 @@
 	if (retval)
 		goto error;
 
-	if (udev->manufacturer) {
-		retval = device_create_file(dev, &dev_attr_manufacturer);
-		if (retval)
-			goto error;
-	}
-	if (udev->product) {
-		retval = device_create_file(dev, &dev_attr_product);
-		if (retval)
-			goto error;
-	}
-	if (udev->serial) {
-		retval = device_create_file(dev, &dev_attr_serial);
-		if (retval)
-			goto error;
-	}
 	retval = usb_create_ep_files(dev, &udev->ep0, udev);
 	if (retval)
 		goto error;
@@ -636,13 +660,9 @@
 	struct device *dev = &udev->dev;
 
 	usb_remove_ep_files(&udev->ep0);
-	device_remove_file(dev, &dev_attr_manufacturer);
-	device_remove_file(dev, &dev_attr_product);
-	device_remove_file(dev, &dev_attr_serial);
 	remove_power_attributes(dev);
 	remove_persist_attributes(dev);
 	device_remove_bin_file(dev, &dev_bin_attr_descriptors);
-	sysfs_remove_group(&dev->kobj, &dev_attr_grp);
 }
 
 /* Interface Accociation Descriptor fields */
@@ -688,17 +708,15 @@
 		struct device_attribute *attr, char *buf)
 {
 	struct usb_interface *intf;
-	struct usb_device *udev;
-	int len;
+	char *string;
 
 	intf = to_usb_interface(dev);
-	udev = interface_to_usbdev(intf);
-	len = snprintf(buf, 256, "%s", intf->cur_altsetting->string);
-	if (len < 0)
+	string = intf->cur_altsetting->string;
+	barrier();		/* The altsetting might change! */
+
+	if (!string)
 		return 0;
-	buf[len] = '\n';
-	buf[len+1] = 0;
-	return len+1;
+	return sprintf(buf, "%s\n", string);
 }
 static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
 
@@ -727,18 +745,6 @@
 }
 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
-static struct attribute *intf_assoc_attrs[] = {
-	&dev_attr_iad_bFirstInterface.attr,
-	&dev_attr_iad_bInterfaceCount.attr,
-	&dev_attr_iad_bFunctionClass.attr,
-	&dev_attr_iad_bFunctionSubClass.attr,
-	&dev_attr_iad_bFunctionProtocol.attr,
-	NULL,
-};
-static struct attribute_group intf_assoc_attr_grp = {
-	.attrs = intf_assoc_attrs,
-};
-
 static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceNumber.attr,
 	&dev_attr_bAlternateSetting.attr,
@@ -753,6 +759,37 @@
 	.attrs = intf_attrs,
 };
 
+static struct attribute *intf_assoc_attrs[] = {
+	&dev_attr_iad_bFirstInterface.attr,
+	&dev_attr_iad_bInterfaceCount.attr,
+	&dev_attr_iad_bFunctionClass.attr,
+	&dev_attr_iad_bFunctionSubClass.attr,
+	&dev_attr_iad_bFunctionProtocol.attr,
+	NULL,
+};
+
+static mode_t intf_assoc_attrs_are_visible(struct kobject *kobj,
+		struct attribute *a, int n)
+{
+	struct usb_interface *intf = to_usb_interface(
+			container_of(kobj, struct device, kobj));
+
+	if (intf->intf_assoc == NULL)
+		return 0;
+	return a->mode;
+}
+
+static struct attribute_group intf_assoc_attr_grp = {
+	.attrs =	intf_assoc_attrs,
+	.is_visible =	intf_assoc_attrs_are_visible,
+};
+
+struct attribute_group *usb_interface_groups[] = {
+	&intf_attr_grp,
+	&intf_assoc_attr_grp,
+	NULL
+};
+
 static inline void usb_create_intf_ep_files(struct usb_interface *intf,
 		struct usb_device *udev)
 {
@@ -777,23 +814,21 @@
 
 int usb_create_sysfs_intf_files(struct usb_interface *intf)
 {
-	struct device *dev = &intf->dev;
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_host_interface *alt = intf->cur_altsetting;
 	int retval;
 
 	if (intf->sysfs_files_created)
 		return 0;
-	retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
-	if (retval)
-		return retval;
 
+	/* The interface string may be present in some altsettings
+	 * and missing in others.  Hence its attribute cannot be created
+	 * before the uevent is broadcast.
+	 */
 	if (alt->string == NULL)
 		alt->string = usb_cache_string(udev, alt->desc.iInterface);
 	if (alt->string)
-		retval = device_create_file(dev, &dev_attr_interface);
-	if (intf->intf_assoc)
-		retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
+		retval = device_create_file(&intf->dev, &dev_attr_interface);
 	usb_create_intf_ep_files(intf, udev);
 	intf->sysfs_files_created = 1;
 	return 0;
@@ -807,7 +842,5 @@
 		return;
 	usb_remove_intf_ep_files(intf);
 	device_remove_file(dev, &dev_attr_interface);
-	sysfs_remove_group(&dev->kobj, &intf_attr_grp);
-	sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
 	intf->sysfs_files_created = 0;
 }
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 1f0db51..3257743 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -291,6 +291,7 @@
 	device_initialize(&dev->dev);
 	dev->dev.bus = &usb_bus_type;
 	dev->dev.type = &usb_device_type;
+	dev->dev.groups = usb_device_groups;
 	dev->dev.dma_mask = bus->controller->dma_mask;
 	set_dev_node(&dev->dev, dev_to_node(bus->controller));
 	dev->state = USB_STATE_ATTACHED;
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1bf8ccb..1a8bc21 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -130,6 +130,10 @@
 /* for labeling diagnostics */
 extern const char *usbcore_name;
 
+/* sysfs stuff */
+extern struct attribute_group *usb_device_groups[];
+extern struct attribute_group *usb_interface_groups[];
+
 /* usbfs stuff */
 extern struct mutex usbfs_mutex;
 extern struct usb_driver usbfs_driver;
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index ce337cb..f261d2a 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -3251,7 +3251,7 @@
 	/* pci setup */
 	if (pci_enable_device(pdev) < 0) {
 		kfree(dev);
-		dev = 0;
+		dev = NULL;
 		retval = -ENODEV;
 		goto finished;
 	}
@@ -3264,7 +3264,7 @@
 	if (!request_mem_region(resource, len, name)) {
 		dev_dbg(&pdev->dev, "pci device used already\n");
 		kfree(dev);
-		dev = 0;
+		dev = NULL;
 		retval = -EBUSY;
 		goto finished;
 	}
@@ -3274,7 +3274,7 @@
 	if (dev->virt_addr == NULL) {
 		dev_dbg(&pdev->dev, "start address cannot be mapped\n");
 		kfree(dev);
-		dev = 0;
+		dev = NULL;
 		retval = -EFAULT;
 		goto finished;
 	}
@@ -3282,7 +3282,7 @@
 	if (!pdev->irq) {
 		dev_err(&dev->pdev->dev, "irq not set\n");
 		kfree(dev);
-		dev = 0;
+		dev = NULL;
 		retval = -ENODEV;
 		goto finished;
 	}
@@ -3290,7 +3290,7 @@
 	if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
 		dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
 		kfree(dev);
-		dev = 0;
+		dev = NULL;
 		retval = -EBUSY;
 		goto finished;
 	}
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index e756023..07e5a0b 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -649,7 +649,13 @@
 
 	if (!ep->desc) {
 		spin_unlock_irqrestore(&udc->lock, flags);
-		DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name);
+		/* REVISIT because this driver disables endpoints in
+		 * reset_all_endpoints() before calling disconnect(),
+		 * most gadget drivers would trigger this non-error ...
+		 */
+		if (udc->gadget.speed != USB_SPEED_UNKNOWN)
+			DBG(DBG_ERR, "ep_disable: %s not enabled\n",
+					ep->ep.name);
 		return -EINVAL;
 	}
 	ep->desc = NULL;
@@ -1032,8 +1038,6 @@
 			.release	= nop_release,
 		},
 	},
-
-	.lock	= SPIN_LOCK_UNLOCKED,
 };
 
 /*
@@ -1052,6 +1056,12 @@
 		request_complete(ep, req, -ECONNRESET);
 	}
 
+	/* NOTE:  normally, the next call to the gadget driver is in
+	 * charge of disabling endpoints... usually disconnect().
+	 * The exception would be entering a high speed test mode.
+	 *
+	 * FIXME remove this code ... and retest thoroughly.
+	 */
 	list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
 		if (ep->desc) {
 			spin_unlock(&udc->lock);
@@ -1219,7 +1229,7 @@
 static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
 		struct usb_ctrlrequest *crq)
 {
-	int retval = 0;;
+	int retval = 0;
 
 	switch (crq->bRequest) {
 	case USB_REQ_GET_STATUS: {
@@ -1693,6 +1703,14 @@
 		usba_writel(udc, INT_CLR, USBA_END_OF_RESET);
 		reset_all_endpoints(udc);
 
+		if (udc->gadget.speed != USB_SPEED_UNKNOWN
+				&& udc->driver->disconnect) {
+			udc->gadget.speed = USB_SPEED_UNKNOWN;
+			spin_unlock(&udc->lock);
+			udc->driver->disconnect(&udc->gadget);
+			spin_lock(&udc->lock);
+		}
+
 		if (status & USBA_HIGH_SPEED) {
 			DBG(DBG_BUS, "High-speed bus reset detected\n");
 			udc->gadget.speed = USB_SPEED_HIGH;
@@ -1716,9 +1734,13 @@
 				| USBA_DET_SUSPEND
 				| USBA_END_OF_RESUME));
 
+		/*
+		 * Unclear why we hit this irregularly, e.g. in usbtest,
+		 * but it's clearly harmless...
+		 */
 		if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED))
-			dev_warn(&udc->pdev->dev,
-				 "WARNING: EP0 configuration is invalid!\n");
+			dev_dbg(&udc->pdev->dev,
+				 "ODD: EP0 configuration is invalid!\n");
 	}
 
 	spin_unlock(&udc->lock);
@@ -1751,9 +1773,11 @@
 			reset_all_endpoints(udc);
 			toggle_bias(0);
 			usba_writel(udc, CTRL, USBA_DISABLE_MASK);
-			spin_unlock(&udc->lock);
-			udc->driver->disconnect(&udc->gadget);
-			spin_lock(&udc->lock);
+			if (udc->driver->disconnect) {
+				spin_unlock(&udc->lock);
+				udc->driver->disconnect(&udc->gadget);
+				spin_lock(&udc->lock);
+			}
 		}
 		udc->vbus_prev = vbus;
 	}
@@ -1825,7 +1849,7 @@
 
 	if (!udc->pdev)
 		return -ENODEV;
-	if (driver != udc->driver)
+	if (driver != udc->driver || !driver->unbind)
 		return -EINVAL;
 
 	if (udc->vbus_pin != -1)
@@ -1840,6 +1864,9 @@
 	toggle_bias(0);
 	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
 
+	if (udc->driver->disconnect)
+		udc->driver->disconnect(&udc->gadget);
+
 	driver->unbind(&udc->gadget);
 	udc->gadget.dev.driver = NULL;
 	udc->driver = NULL;
@@ -1879,6 +1906,7 @@
 		goto err_get_hclk;
 	}
 
+	spin_lock_init(&udc->lock);
 	udc->pdev = pdev;
 	udc->pclk = pclk;
 	udc->hclk = hclk;
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 75eba20..499b7a2 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1546,7 +1546,6 @@
 	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
 	dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0];
 	ep0_idle(dev);
-	strcpy(dev->dev->bus_id, "");
 
 	/* PXA endpoints init */
 	for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
@@ -1746,13 +1745,10 @@
 		ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i);
 	}
 
-	le16_to_cpus(&u.r.wValue);
-	le16_to_cpus(&u.r.wIndex);
-	le16_to_cpus(&u.r.wLength);
-
 	ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n",
 		u.r.bRequestType, u.r.bRequest,
-		u.r.wValue, u.r.wIndex, u.r.wLength);
+		le16_to_cpu(u.r.wValue), le16_to_cpu(u.r.wIndex),
+		le16_to_cpu(u.r.wLength));
 	if (unlikely(have_extrabytes))
 		goto stall;
 
@@ -2296,7 +2292,8 @@
 {
 	struct pxa_udc *udc = platform_get_drvdata(_dev);
 
-	udc_disable(udc);
+	if (udc_readl(udc, UDCCR) & UDCCR_UDE)
+		udc_disable(udc);
 }
 
 #ifdef CONFIG_PM
@@ -2361,9 +2358,8 @@
 	 * Upon exit from sleep mode and before clearing OTGPH,
 	 * Software must configure the USB OTG pad, UDC, and UHC
 	 * to the state they were in before entering sleep mode.
-	 *
-	 * Should be : PSSR |= PSSR_OTGPH;
 	 */
+	PSSR |= PSSR_OTGPH;
 
 	return 0;
 }
@@ -2387,6 +2383,9 @@
 
 static int __init udc_init(void)
 {
+	if (!cpu_is_pxa27x())
+		return -ENODEV;
+
 	printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
 	return platform_driver_probe(&udc_driver, pxa_udc_probe);
 }
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index 1d1b7936..97453db 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -484,4 +484,12 @@
 #define ep_warn(ep, fmt, arg...) \
 	dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg)
 
+/*
+ * Cannot include pxa-regs.h, as register names are similar.
+ * So PSSR is redefined here. This should be removed once UDC registers will
+ * be gone from pxa-regs.h.
+ */
+#define PSSR		__REG(0x40F00004)	/* Power Manager Sleep Status */
+#define PSSR_OTGPH	(1 << 6)		/* OTG Peripheral Hold */
+
 #endif /* __LINUX_USB_GADGET_PXA27X_H */
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 54cdd6f..fa019fa 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -14,7 +14,6 @@
  * This software is distributed under the terms of the GNU General
  * Public License ("GPL") as published by the Free Software Foundation,
  * either version 2 of that License or (at your option) any later version.
- *
  */
 
 #include <linux/kernel.h>
@@ -33,7 +32,7 @@
 /* Defines */
 
 #define GS_VERSION_STR			"v2.2"
-#define GS_VERSION_NUM			0x0202
+#define GS_VERSION_NUM			0x2200
 
 #define GS_LONG_NAME			"Gadget Serial"
 #define GS_SHORT_NAME			"g_serial"
@@ -41,7 +40,11 @@
 #define GS_MAJOR			127
 #define GS_MINOR_START			0
 
-#define GS_NUM_PORTS			16
+/* REVISIT only one port is supported for now;
+ * see gs_{send,recv}_packet() ... no multiplexing,
+ * and no support for multiple ACM devices.
+ */
+#define GS_NUM_PORTS			1
 
 #define GS_NUM_CONFIGS			1
 #define GS_NO_CONFIG_ID			0
@@ -65,6 +68,9 @@
 
 #define GS_DEFAULT_USE_ACM		0
 
+/* 9600-8-N-1 ... matches init_termios.c_cflag and defaults
+ * expected by "usbser.sys" on MS-Windows.
+ */
 #define GS_DEFAULT_DTE_RATE		9600
 #define GS_DEFAULT_DATA_BITS		8
 #define GS_DEFAULT_PARITY		USB_CDC_NO_PARITY
@@ -107,10 +113,6 @@
 #define GS_NOTIFY_MAXPACKET		8
 
 
-/* Structures */
-
-struct gs_dev;
-
 /* circular buffer */
 struct gs_buf {
 	unsigned int		buf_size;
@@ -119,12 +121,6 @@
 	char			*buf_put;
 };
 
-/* list of requests */
-struct gs_req_entry {
-	struct list_head	re_entry;
-	struct usb_request	*re_req;
-};
-
 /* the port structure holds info for each port, one for each minor number */
 struct gs_port {
 	struct gs_dev		*port_dev;	/* pointer to device struct */
@@ -164,26 +160,7 @@
 
 /* Functions */
 
-/* module */
-static int __init gs_module_init(void);
-static void __exit gs_module_exit(void);
-
-/* tty driver */
-static int gs_open(struct tty_struct *tty, struct file *file);
-static void gs_close(struct tty_struct *tty, struct file *file);
-static int gs_write(struct tty_struct *tty,
-	const unsigned char *buf, int count);
-static int gs_put_char(struct tty_struct *tty, unsigned char ch);
-static void gs_flush_chars(struct tty_struct *tty);
-static int gs_write_room(struct tty_struct *tty);
-static int gs_chars_in_buffer(struct tty_struct *tty);
-static void gs_throttle(struct tty_struct * tty);
-static void gs_unthrottle(struct tty_struct * tty);
-static void gs_break(struct tty_struct *tty, int break_state);
-static int  gs_ioctl(struct tty_struct *tty, struct file *file,
-	unsigned int cmd, unsigned long arg);
-static void gs_set_termios(struct tty_struct *tty, struct ktermios *old);
-
+/* tty driver internals */
 static int gs_send(struct gs_dev *dev);
 static int gs_send_packet(struct gs_dev *dev, char *packet,
 	unsigned int size);
@@ -192,19 +169,7 @@
 static void gs_read_complete(struct usb_ep *ep, struct usb_request *req);
 static void gs_write_complete(struct usb_ep *ep, struct usb_request *req);
 
-/* gadget driver */
-static int gs_bind(struct usb_gadget *gadget);
-static void gs_unbind(struct usb_gadget *gadget);
-static int gs_setup(struct usb_gadget *gadget,
-	const struct usb_ctrlrequest *ctrl);
-static int gs_setup_standard(struct usb_gadget *gadget,
-	const struct usb_ctrlrequest *ctrl);
-static int gs_setup_class(struct usb_gadget *gadget,
-	const struct usb_ctrlrequest *ctrl);
-static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req);
-static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
-	struct usb_request *req);
-static void gs_disconnect(struct usb_gadget *gadget);
+/* gadget driver internals */
 static int gs_set_config(struct gs_dev *dev, unsigned config);
 static void gs_reset_config(struct gs_dev *dev);
 static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
@@ -214,10 +179,6 @@
 	gfp_t kmalloc_flags);
 static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
 
-static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
-	gfp_t kmalloc_flags);
-static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
-
 static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
 static void gs_free_ports(struct gs_dev *dev);
 
@@ -232,62 +193,15 @@
 static unsigned int gs_buf_get(struct gs_buf *gb, char *buf,
 	unsigned int count);
 
-/* external functions */
-extern int net2280_set_fifo_mode(struct usb_gadget *gadget, int mode);
-
 
 /* Globals */
 
 static struct gs_dev *gs_device;
 
-static const char *EP_IN_NAME;
-static const char *EP_OUT_NAME;
-static const char *EP_NOTIFY_NAME;
-
 static struct mutex gs_open_close_lock[GS_NUM_PORTS];
 
-static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
-static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
 
-static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE;
-
-static unsigned int use_acm = GS_DEFAULT_USE_ACM;
-
-
-/* tty driver struct */
-static const struct tty_operations gs_tty_ops = {
-	.open =			gs_open,
-	.close =		gs_close,
-	.write =		gs_write,
-	.put_char =		gs_put_char,
-	.flush_chars =		gs_flush_chars,
-	.write_room =		gs_write_room,
-	.ioctl =		gs_ioctl,
-	.set_termios =		gs_set_termios,
-	.throttle =		gs_throttle,
-	.unthrottle =		gs_unthrottle,
-	.break_ctl =		gs_break,
-	.chars_in_buffer =	gs_chars_in_buffer,
-};
-static struct tty_driver *gs_tty_driver;
-
-/* gadget driver struct */
-static struct usb_gadget_driver gs_gadget_driver = {
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-	.speed =		USB_SPEED_HIGH,
-#else
-	.speed =		USB_SPEED_FULL,
-#endif /* CONFIG_USB_GADGET_DUALSPEED */
-	.function =		GS_LONG_NAME,
-	.bind =			gs_bind,
-	.unbind =		gs_unbind,
-	.setup =		gs_setup,
-	.disconnect =		gs_disconnect,
-	.driver = {
-		.name =		GS_SHORT_NAME,
-	},
-};
-
+/*-------------------------------------------------------------------------*/
 
 /* USB descriptors */
 
@@ -304,7 +218,6 @@
 static struct usb_string gs_strings[] = {
 	{ GS_MANUFACTURER_STR_ID, manufacturer },
 	{ GS_PRODUCT_STR_ID, GS_LONG_NAME },
-	{ GS_SERIAL_STR_ID, "0" },
 	{ GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" },
 	{ GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" },
 	{ GS_CONTROL_STR_ID, "Gadget Serial Control" },
@@ -327,7 +240,6 @@
 	.idProduct =		__constant_cpu_to_le16(GS_PRODUCT_ID),
 	.iManufacturer =	GS_MANUFACTURER_STR_ID,
 	.iProduct =		GS_PRODUCT_STR_ID,
-	.iSerialNumber =	GS_SERIAL_STR_ID,
 	.bNumConfigurations =	GS_NUM_CONFIGS,
 };
 
@@ -364,7 +276,7 @@
 	.bDescriptorType =	USB_DT_INTERFACE,
 	.bInterfaceNumber =	GS_BULK_INTERFACE_ID,
 	.bNumEndpoints =	2,
-	.bInterfaceClass =	USB_CLASS_CDC_DATA,
+	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
 	.bInterfaceSubClass =	0,
 	.bInterfaceProtocol =	0,
 	.iInterface =		GS_DATA_STR_ID,
@@ -521,6 +433,8 @@
 };
 
 
+/*-------------------------------------------------------------------------*/
+
 /* Module */
 MODULE_DESCRIPTION(GS_LONG_NAME);
 MODULE_AUTHOR("Al Borchers");
@@ -531,84 +445,23 @@
 MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
 #endif
 
+static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
 module_param(read_q_size, uint, S_IRUGO);
 MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32");
 
+static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
 module_param(write_q_size, uint, S_IRUGO);
 MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32");
 
+static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE;
 module_param(write_buf_size, uint, S_IRUGO);
 MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192");
 
+static unsigned int use_acm = GS_DEFAULT_USE_ACM;
 module_param(use_acm, uint, S_IRUGO);
 MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no");
 
-module_init(gs_module_init);
-module_exit(gs_module_exit);
-
-/*
-*  gs_module_init
-*
-*  Register as a USB gadget driver and a tty driver.
-*/
-static int __init gs_module_init(void)
-{
-	int i;
-	int retval;
-
-	retval = usb_gadget_register_driver(&gs_gadget_driver);
-	if (retval) {
-		pr_err("gs_module_init: cannot register gadget driver, "
-			"ret=%d\n", retval);
-		return retval;
-	}
-
-	gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS);
-	if (!gs_tty_driver)
-		return -ENOMEM;
-	gs_tty_driver->owner = THIS_MODULE;
-	gs_tty_driver->driver_name = GS_SHORT_NAME;
-	gs_tty_driver->name = "ttygs";
-	gs_tty_driver->major = GS_MAJOR;
-	gs_tty_driver->minor_start = GS_MINOR_START;
-	gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
-	gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
-	gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
-	gs_tty_driver->init_termios = tty_std_termios;
-	gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	tty_set_operations(gs_tty_driver, &gs_tty_ops);
-
-	for (i=0; i < GS_NUM_PORTS; i++)
-		mutex_init(&gs_open_close_lock[i]);
-
-	retval = tty_register_driver(gs_tty_driver);
-	if (retval) {
-		usb_gadget_unregister_driver(&gs_gadget_driver);
-		put_tty_driver(gs_tty_driver);
-		pr_err("gs_module_init: cannot register tty driver, "
-				"ret=%d\n", retval);
-		return retval;
-	}
-
-	pr_info("gs_module_init: %s %s loaded\n",
-			GS_LONG_NAME, GS_VERSION_STR);
-	return 0;
-}
-
-/*
-* gs_module_exit
-*
-* Unregister as a tty driver and a USB gadget driver.
-*/
-static void __exit gs_module_exit(void)
-{
-	tty_unregister_driver(gs_tty_driver);
-	put_tty_driver(gs_tty_driver);
-	usb_gadget_unregister_driver(&gs_gadget_driver);
-
-	pr_info("gs_module_exit: %s %s unloaded\n",
-			GS_LONG_NAME, GS_VERSION_STR);
-}
+/*-------------------------------------------------------------------------*/
 
 /* TTY Driver */
 
@@ -753,15 +606,15 @@
  * gs_close
  */
 
-#define GS_WRITE_FINISHED_EVENT_SAFELY(p)			\
-({								\
-	int cond;						\
-								\
-	spin_lock_irq(&(p)->port_lock);				\
-	cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
-	spin_unlock_irq(&(p)->port_lock);			\
-	cond;							\
-})
+static int gs_write_finished_event_safely(struct gs_port *p)
+{
+	int cond;
+
+	spin_lock_irq(&(p)->port_lock);
+	cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf);
+	spin_unlock_irq(&(p)->port_lock);
+	return cond;
+}
 
 static void gs_close(struct tty_struct *tty, struct file *file)
 {
@@ -807,7 +660,7 @@
 	if (gs_buf_data_avail(port->port_write_buf) > 0) {
 		spin_unlock_irq(&port->port_lock);
 		wait_event_interruptible_timeout(port->port_write_wait,
-					GS_WRITE_FINISHED_EVENT_SAFELY(port),
+					gs_write_finished_event_safely(port),
 					GS_CLOSE_TIMEOUT * HZ);
 		spin_lock_irq(&port->port_lock);
 	}
@@ -1065,6 +918,23 @@
 {
 }
 
+static const struct tty_operations gs_tty_ops = {
+	.open =			gs_open,
+	.close =		gs_close,
+	.write =		gs_write,
+	.put_char =		gs_put_char,
+	.flush_chars =		gs_flush_chars,
+	.write_room =		gs_write_room,
+	.ioctl =		gs_ioctl,
+	.set_termios =		gs_set_termios,
+	.throttle =		gs_throttle,
+	.unthrottle =		gs_unthrottle,
+	.break_ctl =		gs_break,
+	.chars_in_buffer =	gs_chars_in_buffer,
+};
+
+/*-------------------------------------------------------------------------*/
+
 /*
 * gs_send
 *
@@ -1080,7 +950,6 @@
 	unsigned long flags;
 	struct usb_ep *ep;
 	struct usb_request *req;
-	struct gs_req_entry *req_entry;
 
 	if (dev == NULL) {
 		pr_err("gs_send: NULL device pointer\n");
@@ -1093,10 +962,8 @@
 
 	while(!list_empty(&dev->dev_req_list)) {
 
-		req_entry = list_entry(dev->dev_req_list.next,
-			struct gs_req_entry, re_entry);
-
-		req = req_entry->re_req;
+		req = list_entry(dev->dev_req_list.next,
+				struct usb_request, list);
 
 		len = gs_send_packet(dev, req->buf, ep->maxpacket);
 
@@ -1106,7 +973,7 @@
 					*((unsigned char *)req->buf),
 					*((unsigned char *)req->buf+1),
 					*((unsigned char *)req->buf+2));
-			list_del(&req_entry->re_entry);
+			list_del(&req->list);
 			req->length = len;
 			spin_unlock_irqrestore(&dev->dev_lock, flags);
 			if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
@@ -1289,7 +1156,6 @@
 static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct gs_dev *dev = ep->driver_data;
-	struct gs_req_entry *gs_req = req->context;
 
 	if (dev == NULL) {
 		pr_err("gs_write_complete: NULL device pointer\n");
@@ -1300,13 +1166,8 @@
 	case 0:
 		/* normal completion */
 requeue:
-		if (gs_req == NULL) {
-			pr_err("gs_write_complete: NULL request pointer\n");
-			return;
-		}
-
 		spin_lock(&dev->dev_lock);
-		list_add(&gs_req->re_entry, &dev->dev_req_list);
+		list_add(&req->list, &dev->dev_req_list);
 		spin_unlock(&dev->dev_lock);
 
 		gs_send(dev);
@@ -1328,9 +1189,39 @@
 	}
 }
 
+/*-------------------------------------------------------------------------*/
+
 /* Gadget Driver */
 
 /*
+ * gs_unbind
+ *
+ * Called on module unload.  Frees the control request and device
+ * structure.
+ */
+static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
+{
+	struct gs_dev *dev = get_gadget_data(gadget);
+
+	gs_device = NULL;
+
+	/* read/write requests already freed, only control request remains */
+	if (dev != NULL) {
+		if (dev->dev_ctrl_req != NULL) {
+			gs_free_req(gadget->ep0, dev->dev_ctrl_req);
+			dev->dev_ctrl_req = NULL;
+		}
+		gs_reset_config(dev);
+		gs_free_ports(dev);
+		kfree(dev);
+		set_gadget_data(gadget, NULL);
+	}
+
+	pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
+		GS_VERSION_STR);
+}
+
+/*
  * gs_bind
  *
  * Called on module load.  Allocates and initializes the device
@@ -1362,19 +1253,23 @@
 			__constant_cpu_to_le16(GS_VERSION_NUM|0x0099);
 	}
 
+	dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
+	if (dev == NULL)
+		return -ENOMEM;
+
 	usb_ep_autoconfig_reset(gadget);
 
 	ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc);
 	if (!ep)
 		goto autoconf_fail;
-	EP_IN_NAME = ep->name;
-	ep->driver_data = ep;	/* claim the endpoint */
+	dev->dev_in_ep = ep;
+	ep->driver_data = dev;	/* claim the endpoint */
 
 	ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc);
 	if (!ep)
 		goto autoconf_fail;
-	EP_OUT_NAME = ep->name;
-	ep->driver_data = ep;	/* claim the endpoint */
+	dev->dev_out_ep = ep;
+	ep->driver_data = dev;	/* claim the endpoint */
 
 	if (use_acm) {
 		ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc);
@@ -1384,8 +1279,8 @@
 		}
 		gs_device_desc.idProduct = __constant_cpu_to_le16(
 						GS_CDC_PRODUCT_ID),
-		EP_NOTIFY_NAME = ep->name;
-		ep->driver_data = ep;	/* claim the endpoint */
+		dev->dev_notify_ep = ep;
+		ep->driver_data = dev;	/* claim the endpoint */
 	}
 
 	gs_device_desc.bDeviceClass = use_acm
@@ -1415,9 +1310,7 @@
 		gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 	}
 
-	gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
-	if (dev == NULL)
-		return -ENOMEM;
+	gs_device = dev;
 
 	snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
 		init_utsname()->sysname, init_utsname()->release,
@@ -1441,8 +1334,6 @@
 		gs_unbind(gadget);
 		return -ENOMEM;
 	}
-	dev->dev_ctrl_req->complete = gs_setup_complete;
-
 	gadget->ep0->driver_data = dev;
 
 	pr_info("gs_bind: %s %s bound\n",
@@ -1451,99 +1342,11 @@
 	return 0;
 
 autoconf_fail:
+	kfree(dev);
 	pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name);
 	return -ENODEV;
 }
 
-/*
- * gs_unbind
- *
- * Called on module unload.  Frees the control request and device
- * structure.
- */
-static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
-{
-	struct gs_dev *dev = get_gadget_data(gadget);
-
-	gs_device = NULL;
-
-	/* read/write requests already freed, only control request remains */
-	if (dev != NULL) {
-		if (dev->dev_ctrl_req != NULL) {
-			gs_free_req(gadget->ep0, dev->dev_ctrl_req);
-			dev->dev_ctrl_req = NULL;
-		}
-		gs_free_ports(dev);
-		if (dev->dev_notify_ep)
-			usb_ep_disable(dev->dev_notify_ep);
-		if (dev->dev_in_ep)
-			usb_ep_disable(dev->dev_in_ep);
-		if (dev->dev_out_ep)
-			usb_ep_disable(dev->dev_out_ep);
-		kfree(dev);
-		set_gadget_data(gadget, NULL);
-	}
-
-	pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
-		GS_VERSION_STR);
-}
-
-/*
- * gs_setup
- *
- * Implements all the control endpoint functionality that's not
- * handled in hardware or the hardware driver.
- *
- * Returns the size of the data sent to the host, or a negative
- * error number.
- */
-static int gs_setup(struct usb_gadget *gadget,
-	const struct usb_ctrlrequest *ctrl)
-{
-	int ret = -EOPNOTSUPP;
-	struct gs_dev *dev = get_gadget_data(gadget);
-	struct usb_request *req = dev->dev_ctrl_req;
-	u16 wIndex = le16_to_cpu(ctrl->wIndex);
-	u16 wValue = le16_to_cpu(ctrl->wValue);
-	u16 wLength = le16_to_cpu(ctrl->wLength);
-
-	req->complete = gs_setup_complete;
-
-	switch (ctrl->bRequestType & USB_TYPE_MASK) {
-	case USB_TYPE_STANDARD:
-		ret = gs_setup_standard(gadget,ctrl);
-		break;
-
-	case USB_TYPE_CLASS:
-		ret = gs_setup_class(gadget,ctrl);
-		break;
-
-	default:
-		pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
-			"value=%04x, index=%04x, length=%d\n",
-			ctrl->bRequestType, ctrl->bRequest,
-			wValue, wIndex, wLength);
-		break;
-	}
-
-	/* respond with data transfer before status phase? */
-	if (ret >= 0) {
-		req->length = ret;
-		req->zero = ret < wLength
-				&& (ret % gadget->ep0->maxpacket) == 0;
-		ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
-		if (ret < 0) {
-			pr_err("gs_setup: cannot queue response, ret=%d\n",
-				ret);
-			req->status = 0;
-			gs_setup_complete(gadget->ep0, req);
-		}
-	}
-
-	/* device either stalls (ret < 0) or reports success */
-	return ret;
-}
-
 static int gs_setup_standard(struct usb_gadget *gadget,
 	const struct usb_ctrlrequest *ctrl)
 {
@@ -1673,6 +1476,42 @@
 	return ret;
 }
 
+static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
+		struct usb_request *req)
+{
+	struct gs_dev *dev = ep->driver_data;
+	struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
+
+	switch (req->status) {
+	case 0:
+		/* normal completion */
+		if (req->actual != sizeof(port->port_line_coding))
+			usb_ep_set_halt(ep);
+		else if (port) {
+			struct usb_cdc_line_coding	*value = req->buf;
+
+			/* REVISIT:  we currently just remember this data.
+			 * If we change that, (a) validate it first, then
+			 * (b) update whatever hardware needs updating.
+			 */
+			spin_lock(&port->port_lock);
+			port->port_line_coding = *value;
+			spin_unlock(&port->port_lock);
+		}
+		break;
+
+	case -ESHUTDOWN:
+		/* disconnect */
+		gs_free_req(ep, req);
+		break;
+
+	default:
+		/* unexpected */
+		break;
+	}
+	return;
+}
+
 static int gs_setup_class(struct usb_gadget *gadget,
 	const struct usb_ctrlrequest *ctrl)
 {
@@ -1734,42 +1573,6 @@
 	return ret;
 }
 
-static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
-		struct usb_request *req)
-{
-	struct gs_dev *dev = ep->driver_data;
-	struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
-
-	switch (req->status) {
-	case 0:
-		/* normal completion */
-		if (req->actual != sizeof(port->port_line_coding))
-			usb_ep_set_halt(ep);
-		else if (port) {
-			struct usb_cdc_line_coding	*value = req->buf;
-
-			/* REVISIT:  we currently just remember this data.
-			 * If we change that, (a) validate it first, then
-			 * (b) update whatever hardware needs updating.
-			 */
-			spin_lock(&port->port_lock);
-			port->port_line_coding = *value;
-			spin_unlock(&port->port_lock);
-		}
-		break;
-
-	case -ESHUTDOWN:
-		/* disconnect */
-		gs_free_req(ep, req);
-		break;
-
-	default:
-		/* unexpected */
-		break;
-	}
-	return;
-}
-
 /*
  * gs_setup_complete
  */
@@ -1783,6 +1586,62 @@
 }
 
 /*
+ * gs_setup
+ *
+ * Implements all the control endpoint functionality that's not
+ * handled in hardware or the hardware driver.
+ *
+ * Returns the size of the data sent to the host, or a negative
+ * error number.
+ */
+static int gs_setup(struct usb_gadget *gadget,
+	const struct usb_ctrlrequest *ctrl)
+{
+	int		ret = -EOPNOTSUPP;
+	struct gs_dev	*dev = get_gadget_data(gadget);
+	struct usb_request *req = dev->dev_ctrl_req;
+	u16		wIndex = le16_to_cpu(ctrl->wIndex);
+	u16		wValue = le16_to_cpu(ctrl->wValue);
+	u16		wLength = le16_to_cpu(ctrl->wLength);
+
+	req->complete = gs_setup_complete;
+
+	switch (ctrl->bRequestType & USB_TYPE_MASK) {
+	case USB_TYPE_STANDARD:
+		ret = gs_setup_standard(gadget, ctrl);
+		break;
+
+	case USB_TYPE_CLASS:
+		ret = gs_setup_class(gadget, ctrl);
+		break;
+
+	default:
+		pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
+			"value=%04x, index=%04x, length=%d\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			wValue, wIndex, wLength);
+		break;
+	}
+
+	/* respond with data transfer before status phase? */
+	if (ret >= 0) {
+		req->length = ret;
+		req->zero = ret < wLength
+				&& (ret % gadget->ep0->maxpacket) == 0;
+		ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
+		if (ret < 0) {
+			pr_err("gs_setup: cannot queue response, ret=%d\n",
+				ret);
+			req->status = 0;
+			gs_setup_complete(gadget->ep0, req);
+		}
+	}
+
+	/* device either stalls (ret < 0) or reports success */
+	return ret;
+}
+
+/*
  * gs_disconnect
  *
  * Called when the device is disconnected.  Frees the closed
@@ -1811,6 +1670,23 @@
 	pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME);
 }
 
+static struct usb_gadget_driver gs_gadget_driver = {
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+	.speed =		USB_SPEED_HIGH,
+#else
+	.speed =		USB_SPEED_FULL,
+#endif /* CONFIG_USB_GADGET_DUALSPEED */
+	.function =		GS_LONG_NAME,
+	.bind =			gs_bind,
+	.unbind =		gs_unbind,
+	.setup =		gs_setup,
+	.disconnect =		gs_disconnect,
+	.driver = {
+		.name =		GS_SHORT_NAME,
+		.owner =	THIS_MODULE,
+	},
+};
+
 /*
  * gs_set_config
  *
@@ -1826,9 +1702,8 @@
 	int ret = 0;
 	struct usb_gadget *gadget = dev->dev_gadget;
 	struct usb_ep *ep;
-	struct usb_endpoint_descriptor *ep_desc;
+	struct usb_endpoint_descriptor *out, *in, *notify;
 	struct usb_request *req;
-	struct gs_req_entry *req_entry;
 
 	if (dev == NULL) {
 		pr_err("gs_set_config: NULL device pointer\n");
@@ -1846,86 +1721,62 @@
 	case GS_BULK_CONFIG_ID:
 		if (use_acm)
 			return -EINVAL;
-		/* device specific optimizations */
-		if (gadget_is_net2280(gadget))
-			net2280_set_fifo_mode(gadget, 1);
 		break;
 	case GS_ACM_CONFIG_ID:
 		if (!use_acm)
 			return -EINVAL;
-		/* device specific optimizations */
-		if (gadget_is_net2280(gadget))
-			net2280_set_fifo_mode(gadget, 1);
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	dev->dev_config = config;
-
-	gadget_for_each_ep(ep, gadget) {
-
-		if (EP_NOTIFY_NAME
-		&& strcmp(ep->name, EP_NOTIFY_NAME) == 0) {
-			ep_desc = choose_ep_desc(gadget,
+	in = choose_ep_desc(gadget,
+			&gs_highspeed_in_desc,
+			&gs_fullspeed_in_desc);
+	out = choose_ep_desc(gadget,
+			&gs_highspeed_out_desc,
+			&gs_fullspeed_out_desc);
+	notify = dev->dev_notify_ep
+		? choose_ep_desc(gadget,
 				&gs_highspeed_notify_desc,
-				&gs_fullspeed_notify_desc);
-			ret = usb_ep_enable(ep,ep_desc);
-			if (ret == 0) {
-				ep->driver_data = dev;
-				dev->dev_notify_ep = ep;
-				dev->dev_notify_ep_desc = ep_desc;
-			} else {
-				pr_err("gs_set_config: cannot enable NOTIFY "
-					"endpoint %s, ret=%d\n",
-					ep->name, ret);
-				goto exit_reset_config;
-			}
-		}
+				&gs_fullspeed_notify_desc)
+		: NULL;
 
-		else if (strcmp(ep->name, EP_IN_NAME) == 0) {
-			ep_desc = choose_ep_desc(gadget,
-				&gs_highspeed_in_desc,
-				&gs_fullspeed_in_desc);
-			ret = usb_ep_enable(ep,ep_desc);
-			if (ret == 0) {
-				ep->driver_data = dev;
-				dev->dev_in_ep = ep;
-				dev->dev_in_ep_desc = ep_desc;
-			} else {
-				pr_err("gs_set_config: cannot enable IN "
-					"endpoint %s, ret=%d\n",
-					ep->name, ret);
-				goto exit_reset_config;
-			}
-		}
-
-		else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
-			ep_desc = choose_ep_desc(gadget,
-				&gs_highspeed_out_desc,
-				&gs_fullspeed_out_desc);
-			ret = usb_ep_enable(ep,ep_desc);
-			if (ret == 0) {
-				ep->driver_data = dev;
-				dev->dev_out_ep = ep;
-				dev->dev_out_ep_desc = ep_desc;
-			} else {
-				pr_err("gs_set_config: cannot enable OUT "
-					"endpoint %s, ret=%d\n",
-					ep->name, ret);
-				goto exit_reset_config;
-			}
-		}
-
+	ret = usb_ep_enable(dev->dev_in_ep, in);
+	if (ret == 0) {
+		dev->dev_in_ep_desc = in;
+	} else {
+		pr_debug("%s: cannot enable %s %s, ret=%d\n",
+			__func__, "IN", dev->dev_in_ep->name, ret);
+		return ret;
 	}
 
-	if (dev->dev_in_ep == NULL || dev->dev_out_ep == NULL
-	|| (config != GS_BULK_CONFIG_ID && dev->dev_notify_ep == NULL)) {
-		pr_err("gs_set_config: cannot find endpoints\n");
-		ret = -ENODEV;
-		goto exit_reset_config;
+	ret = usb_ep_enable(dev->dev_out_ep, out);
+	if (ret == 0) {
+		dev->dev_out_ep_desc = out;
+	} else {
+		pr_debug("%s: cannot enable %s %s, ret=%d\n",
+			__func__, "OUT", dev->dev_out_ep->name, ret);
+fail0:
+		usb_ep_disable(dev->dev_in_ep);
+		return ret;
 	}
 
+	if (notify) {
+		ret = usb_ep_enable(dev->dev_notify_ep, notify);
+		if (ret == 0) {
+			dev->dev_notify_ep_desc = notify;
+		} else {
+			pr_debug("%s: cannot enable %s %s, ret=%d\n",
+				__func__, "NOTIFY",
+				dev->dev_notify_ep->name, ret);
+			usb_ep_disable(dev->dev_out_ep);
+			goto fail0;
+		}
+	}
+
+	dev->dev_config = config;
+
 	/* allocate and queue read requests */
 	ep = dev->dev_out_ep;
 	for (i=0; i<read_q_size && ret == 0; i++) {
@@ -1946,9 +1797,10 @@
 	/* allocate write requests, and put on free list */
 	ep = dev->dev_in_ep;
 	for (i=0; i<write_q_size; i++) {
-		if ((req_entry=gs_alloc_req_entry(ep, ep->maxpacket, GFP_ATOMIC))) {
-			req_entry->re_req->complete = gs_write_complete;
-			list_add(&req_entry->re_entry, &dev->dev_req_list);
+		req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
+		if (req) {
+			req->complete = gs_write_complete;
+			list_add(&req->list, &dev->dev_req_list);
 		} else {
 			pr_err("gs_set_config: cannot allocate "
 					"write requests\n");
@@ -1986,7 +1838,7 @@
  */
 static void gs_reset_config(struct gs_dev *dev)
 {
-	struct gs_req_entry *req_entry;
+	struct usb_request *req;
 
 	if (dev == NULL) {
 		pr_err("gs_reset_config: NULL device pointer\n");
@@ -2000,26 +1852,18 @@
 
 	/* free write requests on the free list */
 	while(!list_empty(&dev->dev_req_list)) {
-		req_entry = list_entry(dev->dev_req_list.next,
-			struct gs_req_entry, re_entry);
-		list_del(&req_entry->re_entry);
-		gs_free_req_entry(dev->dev_in_ep, req_entry);
+		req = list_entry(dev->dev_req_list.next,
+				struct usb_request, list);
+		list_del(&req->list);
+		gs_free_req(dev->dev_in_ep, req);
 	}
 
 	/* disable endpoints, forcing completion of pending i/o; */
 	/* completion handlers free their requests in this case */
-	if (dev->dev_notify_ep) {
+	if (dev->dev_notify_ep)
 		usb_ep_disable(dev->dev_notify_ep);
-		dev->dev_notify_ep = NULL;
-	}
-	if (dev->dev_in_ep) {
-		usb_ep_disable(dev->dev_in_ep);
-		dev->dev_in_ep = NULL;
-	}
-	if (dev->dev_out_ep) {
-		usb_ep_disable(dev->dev_out_ep);
-		dev->dev_out_ep = NULL;
-	}
+	usb_ep_disable(dev->dev_in_ep);
+	usb_ep_disable(dev->dev_out_ep);
 }
 
 /*
@@ -2113,46 +1957,6 @@
 }
 
 /*
- * gs_alloc_req_entry
- *
- * Allocates a request and its buffer, using the given
- * endpoint, buffer len, and kmalloc flags.
- */
-static struct gs_req_entry *
-gs_alloc_req_entry(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
-{
-	struct gs_req_entry	*req;
-
-	req = kmalloc(sizeof(struct gs_req_entry), kmalloc_flags);
-	if (req == NULL)
-		return NULL;
-
-	req->re_req = gs_alloc_req(ep, len, kmalloc_flags);
-	if (req->re_req == NULL) {
-		kfree(req);
-		return NULL;
-	}
-
-	req->re_req->context = req;
-
-	return req;
-}
-
-/*
- * gs_free_req_entry
- *
- * Frees a request and its buffer.
- */
-static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req)
-{
-	if (ep != NULL && req != NULL) {
-		if (req->re_req != NULL)
-			gs_free_req(ep, req->re_req);
-		kfree(req);
-	}
-}
-
-/*
  * gs_alloc_ports
  *
  * Allocate all ports and set the gs_dev struct to point to them.
@@ -2233,6 +2037,8 @@
 	}
 }
 
+/*-------------------------------------------------------------------------*/
+
 /* Circular Buffer */
 
 /*
@@ -2393,3 +2199,77 @@
 
 	return count;
 }
+
+/*-------------------------------------------------------------------------*/
+
+static struct tty_driver *gs_tty_driver;
+
+/*
+ *  gs_module_init
+ *
+ *  Register as a USB gadget driver and a tty driver.
+ */
+static int __init gs_module_init(void)
+{
+	int i;
+	int retval;
+
+	retval = usb_gadget_register_driver(&gs_gadget_driver);
+	if (retval) {
+		pr_err("gs_module_init: cannot register gadget driver, "
+			"ret=%d\n", retval);
+		return retval;
+	}
+
+	gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS);
+	if (!gs_tty_driver)
+		return -ENOMEM;
+	gs_tty_driver->owner = THIS_MODULE;
+	gs_tty_driver->driver_name = GS_SHORT_NAME;
+	gs_tty_driver->name = "ttygs";
+	gs_tty_driver->major = GS_MAJOR;
+	gs_tty_driver->minor_start = GS_MINOR_START;
+	gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+	gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+	gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+	gs_tty_driver->init_termios = tty_std_termios;
+	/* must match GS_DEFAULT_DTE_RATE and friends */
+	gs_tty_driver->init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	gs_tty_driver->init_termios.c_ispeed = GS_DEFAULT_DTE_RATE;
+	gs_tty_driver->init_termios.c_ospeed = GS_DEFAULT_DTE_RATE;
+	tty_set_operations(gs_tty_driver, &gs_tty_ops);
+
+	for (i = 0; i < GS_NUM_PORTS; i++)
+		mutex_init(&gs_open_close_lock[i]);
+
+	retval = tty_register_driver(gs_tty_driver);
+	if (retval) {
+		usb_gadget_unregister_driver(&gs_gadget_driver);
+		put_tty_driver(gs_tty_driver);
+		pr_err("gs_module_init: cannot register tty driver, "
+				"ret=%d\n", retval);
+		return retval;
+	}
+
+	pr_info("gs_module_init: %s %s loaded\n",
+			GS_LONG_NAME, GS_VERSION_STR);
+	return 0;
+}
+module_init(gs_module_init);
+
+/*
+ * gs_module_exit
+ *
+ * Unregister as a tty driver and a USB gadget driver.
+ */
+static void __exit gs_module_exit(void)
+{
+	tty_unregister_driver(gs_tty_driver);
+	put_tty_driver(gs_tty_driver);
+	usb_gadget_unregister_driver(&gs_gadget_driver);
+
+	pr_info("gs_module_exit: %s %s unloaded\n",
+			GS_LONG_NAME, GS_VERSION_STR);
+}
+module_exit(gs_module_exit);
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 33b467a..1ef6df3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -129,7 +129,7 @@
 
 config USB_ISP1760_OF
 	bool "Support for the OF platform bus"
-	depends on USB_ISP1760_HCD && OF
+	depends on USB_ISP1760_HCD && PPC_OF
 	---help---
 	  Enables support for the device present on the PowerPC
 	  OpenFirmware platform bus.
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 4ba96c1..c9cec87 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -988,7 +988,7 @@
 			 * This did not trigger for a long time now.
 			 */
 			printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: "
-					"%d of %d done: %08x cur: %08x\n", qtd,
+					"%d of %zu done: %08x cur: %08x\n", qtd,
 					urb, qh, PTD_XFERRED_LENGTH(dw3),
 					qtd->length, done_map,
 					(1 << queue_entry));
@@ -1088,7 +1088,7 @@
 		} else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) {
 			/* short BULK received */
 
-			printk(KERN_ERR "short bulk, %d instead %d\n", length,
+			printk(KERN_ERR "short bulk, %d instead %zu\n", length,
 					qtd->length);
 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
 				urb->status = -EREMOTEIO;
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 73fb2a3..440bf94 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -256,7 +256,7 @@
 
 static int __init isp1760_init(void)
 {
-	int ret;
+	int ret = -ENODEV;
 
 	init_kmem_once();
 
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index 77204f0..e899a77 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -90,7 +90,7 @@
 	struct device *dev = &pdev->dev;
 	struct resource	*res, *mem;
 	int retval, irq;
-	struct usb_hcd *hcd = 0;
+	struct usb_hcd *hcd = NULL;
 
 	irq = retval = platform_get_irq(pdev, 0);
 	if (retval < 0)
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 7aafd53..189a9db 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -63,9 +63,6 @@
 #define USB_DEVICE_ID_VERNIER_CYCLOPS	0x0004
 #define USB_DEVICE_ID_VERNIER_LCSPEC	0x0006
 
-#define USB_VENDOR_ID_MICROCHIP		0x04d8
-#define USB_DEVICE_ID_PICDEM		0x000c
-
 #ifdef CONFIG_USB_DYNAMIC_MINORS
 #define USB_LD_MINOR_BASE	0
 #else
@@ -92,7 +89,6 @@
 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
-	{ USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) },
 	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) },
 	{ }					/* Terminating entry */
 };
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 742be3c..054dedd 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -856,6 +856,11 @@
 		struct urb		*u;
 		struct usb_ctrlrequest	req;
 		struct subcase		*reqp;
+
+		/* sign of this variable means:
+		 *  -: tested code must return this (negative) error code
+		 *  +: tested code may return this (negative too) error code
+		 */
 		int			expected = 0;
 
 		/* requests here are mostly expected to succeed on any
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 2cffec8..9ba64cc 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -447,6 +447,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called mos7840.  If unsure, choose N.
 
+config USB_SERIAL_MOTOROLA
+	tristate "USB Motorola Phone modem driver"
+	---help---
+	  Say Y here if you want to use a Motorola phone with a USB
+	  connector as a modem link.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called moto_modem.  If unsure, choose N.
+
 config USB_SERIAL_NAVMAN
 	tristate "USB Navman GPS device"
 	help
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 7568595..17a762a 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -39,6 +39,7 @@
 obj-$(CONFIG_USB_SERIAL_MCT_U232)		+= mct_u232.o
 obj-$(CONFIG_USB_SERIAL_MOS7720)		+= mos7720.o
 obj-$(CONFIG_USB_SERIAL_MOS7840)		+= mos7840.o
+obj-$(CONFIG_USB_SERIAL_MOTOROLA)		+= moto_modem.o
 obj-$(CONFIG_USB_SERIAL_NAVMAN)			+= navman.o
 obj-$(CONFIG_USB_SERIAL_OMNINET)		+= omninet.o
 obj-$(CONFIG_USB_SERIAL_OPTION)			+= option.o
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index dc0ea08..f5b57b1 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -73,6 +73,7 @@
 	{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
 	{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
 	{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+	{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
 	{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
 	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
 	{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 8a21764..a01e987 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -643,7 +643,7 @@
 static int iuu_bulk_write(struct usb_serial_port *port)
 {
 	struct iuu_private *priv = usb_get_serial_port_data(port);
-	unsigned int flags;
+	unsigned long flags;
 	int result;
 	int i;
 	char *buf_ptr = port->write_urb->transfer_buffer;
@@ -694,7 +694,7 @@
 {
 	struct usb_serial_port *port = urb->context;
 	struct iuu_private *priv = usb_get_serial_port_data(port);
-	unsigned int flags;
+	unsigned long flags;
 	int status;
 	int error = 0;
 	int len = 0;
@@ -759,7 +759,7 @@
 			  int count)
 {
 	struct iuu_private *priv = usb_get_serial_port_data(port);
-	unsigned int flags;
+	unsigned long flags;
 	dbg("%s - enter", __func__);
 
 	if (count > 256)
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c
new file mode 100644
index 0000000..2e8e0546
--- /dev/null
+++ b/drivers/usb/serial/moto_modem.c
@@ -0,0 +1,70 @@
+/*
+ * Motorola USB Phone driver
+ *
+ * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com>
+ *
+ *  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.
+ *
+ * {sigh}
+ * Mororola should be using the CDC ACM USB spec, but instead
+ * they try to just "do their own thing"...  This driver should handle a
+ * few phones in which a basic "dumb serial connection" is needed to be
+ * able to get a connection through to them.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+static struct usb_device_id id_table [] = {
+	{ USB_DEVICE(0x05c6, 0x3197) },	/* unknown Motorola phone */
+	{ USB_DEVICE(0x0c44, 0x0022) },	/* unknown Mororola phone */
+	{ USB_DEVICE(0x22b8, 0x2a64) },	/* Motorola KRZR K1m */
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver moto_driver = {
+	.name =		"moto-modem",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+	.no_dynamic_id = 	1,
+};
+
+static struct usb_serial_driver moto_device = {
+	.driver = {
+		.owner =	THIS_MODULE,
+		.name =		"moto-modem",
+	},
+	.id_table =		id_table,
+	.num_ports =		1,
+};
+
+static int __init moto_init(void)
+{
+	int retval;
+
+	retval = usb_serial_register(&moto_device);
+	if (retval)
+		return retval;
+	retval = usb_register(&moto_driver);
+	if (retval)
+		usb_serial_deregister(&moto_device);
+	return retval;
+}
+
+static void __exit moto_exit(void)
+{
+	usb_deregister(&moto_driver);
+	usb_serial_deregister(&moto_device);
+}
+
+module_init(moto_init);
+module_exit(moto_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e4be2d4..e7e016e 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -154,8 +154,6 @@
 #define NOVATELWIRELESS_PRODUCT_MC727		0x4100
 #define NOVATELWIRELESS_PRODUCT_MC950D		0x4400
 
-#define NOVATELWIRELESS_PRODUCT_U727		0x5010
-
 /* FUTURE NOVATEL PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_EVDO_1		0x6000
 #define NOVATELWIRELESS_PRODUCT_HSPA_1		0x7000
@@ -184,6 +182,9 @@
 #define AXESSTEL_VENDOR_ID			0x1726
 #define AXESSTEL_PRODUCT_MV110H			0x1000
 
+#define ONDA_VENDOR_ID				0x19d2
+#define ONDA_PRODUCT_ET502HS			0x0002
+
 #define BANDRICH_VENDOR_ID			0x1A8D
 #define BANDRICH_PRODUCT_C100_1			0x1002
 #define BANDRICH_PRODUCT_C100_2			0x1003
@@ -269,7 +270,6 @@
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
-	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel U727 */
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */
@@ -293,14 +293,17 @@
 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8136) },	/* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8137) },	/* Dell Wireless HSDPA 5520 */
+	{ USB_DEVICE(DELL_VENDOR_ID, 0x8138) },	/* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
 	{ USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
+	{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
 	{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
 	{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
 	{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
+	{ USB_DEVICE(0x19d2, 0x0001) }, 	/* Telstra NextG CDMA */
 	{ } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index a0ed889..1b09578 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -401,6 +401,14 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
+UNUSUAL_DEV(  0x04b4, 0x6830, 0x0000, 0x9999,
+		"Cypress",
+		"Cypress AT2LP",
+		US_SC_CYP_ATACB, US_PR_BULK, NULL,
+		0),
+#endif
+
 /* Reported by Simon Levitt <simon@whattf.com>
  * This entry needs Sub and Proto fields */
 UNUSUAL_DEV(  0x04b8, 0x0601, 0x0100, 0x0100,
@@ -539,17 +547,6 @@
 		"CD-RW Device",
 		US_SC_8020, US_PR_CB, NULL, 0),
 
-/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
- * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
- * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
- */
-
-UNUSUAL_DEV(  0x04fc, 0x80c2, 0x0100, 0x0100,
-		"Kobian Mercury",
-		"Binocam DCB-132",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_BULK32),
-
 #ifdef CONFIG_USB_STORAGE_USBAT
 UNUSUAL_DEV(  0x04e6, 0x1010, 0x0000, 0x9999,
 		"Shuttle/SCM",
@@ -565,6 +562,16 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_MAX_SECTORS_64),
 
+/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
+ * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
+ * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
+ */
+UNUSUAL_DEV(  0x04fc, 0x80c2, 0x0100, 0x0100,
+		"Kobian Mercury",
+		"Binocam DCB-132",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_BULK32),
+
 /* Reported by Bob Sass <rls@vectordb.com> -- only rev 1.33 tested */
 UNUSUAL_DEV(  0x050d, 0x0115, 0x0133, 0x0133,
 		"Belkin",
@@ -1304,6 +1311,16 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_DEVICE ),
 
+/* Reported by F. Aben <f.aben@option.com>
+ * This device (wrongly) has a vendor-specific device descriptor.
+ * The entry is needed so usb-storage can bind to it's mass-storage
+ * interface as an interface driver */
+UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000,
+		"Option",
+		"GI 0401 SD-Card",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		0 ),
+
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
 		"ATI",
@@ -1361,13 +1378,6 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY),
 
-/* Reported by Rohan Hart <rohan.hart17@gmail.com> */
-UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
-		"INTOVA",
-		"Pixtreme",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
-
 /*
  * Entry for Jenoptik JD 5200z3
  *
@@ -1684,6 +1694,16 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Mauro Andreolini <andreoli@weblab.ing.unimo.it>
+ * This entry is needed to bypass the ZeroCD mechanism
+ * and to properly load as a modem device.
+ */
+UNUSUAL_DEV(  0x19d2, 0x2000, 0x0000, 0x0000,
+		"Onda ET502HS",
+		"USB MMC Storage",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_DEVICE),
+
 /* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
  * and Renato Perini <rperini@email.it>
  */
@@ -1721,6 +1741,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_GO_SLOW ),
 
+/* Reported by Rohan Hart <rohan.hart17@gmail.com> */
+UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
+		"INTOVA",
+		"Pixtreme",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_CAPACITY ),
+
 /*
  * David Härdeman <david@2gen.com>
  * The key makes the SCSI stack print confusing (but harmless) messages
@@ -1745,14 +1772,6 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_CAPACITY_HEURISTICS),
 
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-UNUSUAL_DEV(  0x04b4, 0x6830, 0x0000, 0x9999,
-		"Cypress",
-		"Cypress AT2LP",
-		US_SC_CYP_ATACB, US_PR_BULK, NULL,
-		0),
-#endif
-
 /* Control/Bulk transport for all SubClass values */
 USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
 USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index bb1dada..2cdaf1f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -171,7 +171,6 @@
 config FB_DEFERRED_IO
 	bool
 	depends on FB
-	default y
 
 config FB_METRONOME
 	tristate
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 8ffdf35..b004036 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -441,14 +441,15 @@
 
 	value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));
 
-	value = (value / 2) - 1;
-	dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n", value);
-
-	if (value <= 0) {
+	if (value < 2) {
 		dev_notice(info->device, "Bypassing pixel clock divider\n");
 		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
 	} else {
-		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET);
+		value = (value / 2) - 1;
+		dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n",
+				value);
+		lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1,
+				value << ATMEL_LCDC_CLKVAL_OFFSET);
 		info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1)));
 		dev_dbg(info->device, "  updated pixclk:     %lu KHz\n",
 					PICOS2KHZ(info->var.pixclock));
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 275d9da..e721644 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -17,11 +17,9 @@
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -299,7 +297,7 @@
 	par->physbase = op->resource[0].start;
 	par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-	sbusfb_fill_var(&info->var, dp->node, 1);
+	sbusfb_fill_var(&info->var, dp, 1);
 	linebytes = of_getintprop_default(dp, "linebytes",
 					  info->var.xres);
 
@@ -329,7 +327,7 @@
 	if (!info->screen_base)
 		goto out_unmap_regs;
 
-	bw2_blank(0, info);
+	bw2_blank(FB_BLANK_UNBLANK, info);
 
 	bw2_init_fix(info, linebytes);
 
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 0db0fec..b17e746 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -17,10 +17,9 @@
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -482,7 +481,7 @@
 
 	spin_lock_init(&par->lock);
 
-	sbusfb_fill_var(&info->var, dp->node, 8);
+	sbusfb_fill_var(&info->var, dp, 8);
 	info->var.red.length = 8;
 	info->var.green.length = 8;
 	info->var.blue.length = 8;
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 010ea53..3aa7b6c 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -17,11 +17,9 @@
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -373,7 +371,7 @@
 	par->physbase = op->resource[0].start;
 	par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-	sbusfb_fill_var(&info->var, dp->node, 8);
+	sbusfb_fill_var(&info->var, dp, 8);
 	info->var.red.length = 8;
 	info->var.green.length = 8;
 	info->var.blue.length = 8;
@@ -398,7 +396,7 @@
 	if (!info->screen_base)
 		goto out_unmap_regs;
 
-	cg3_blank(0, info);
+	cg3_blank(FB_BLANK_UNBLANK, info);
 
 	if (!of_find_property(dp, "width", NULL)) {
 		err = cg3_do_default_mode(par);
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index fc90db6..2f64bb3 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -17,9 +17,9 @@
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -728,7 +728,7 @@
 	par->physbase = op->resource[0].start;
 	par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-	sbusfb_fill_var(&info->var, dp->node, 8);
+	sbusfb_fill_var(&info->var, dp, 8);
 	info->var.red.length = 8;
 	info->var.green.length = 8;
 	info->var.blue.length = 8;
@@ -767,7 +767,7 @@
 
 	cg6_bt_init(par);
 	cg6_chip_init(info);
-	cg6_blank(0, info);
+	cg6_blank(FB_BLANK_UNBLANK, info);
 
 	if (fb_alloc_cmap(&info->cmap, 256, 0))
 		goto out_unmap_regs;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index ad31983..5fa8b76 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -1853,6 +1853,8 @@
 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
 	struct display *p = &fb_display[vc->vc_num];
 	int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
+	unsigned short saved_ec;
+	int ret;
 
 	if (fbcon_is_inactive(vc, info))
 		return -EINVAL;
@@ -1865,6 +1867,11 @@
 	 *           whole screen (prevents flicker).
 	 */
 
+	saved_ec = vc->vc_video_erase_char;
+	vc->vc_video_erase_char = vc->vc_scrl_erase_char;
+
+	ret = 0;
+
 	switch (dir) {
 	case SM_UP:
 		if (count > vc->vc_rows)	/* Maximum realistic size */
@@ -1883,7 +1890,7 @@
 							(b - count)),
 				    vc->vc_scrl_erase_char,
 				    vc->vc_size_row * count);
-			return 1;
+			ret = 1;
 			break;
 
 		case SCROLL_WRAP_MOVE:
@@ -1955,7 +1962,8 @@
 							(b - count)),
 				    vc->vc_scrl_erase_char,
 				    vc->vc_size_row * count);
-			return 1;
+			ret = 1;
+			break;
 		}
 		break;
 
@@ -1974,7 +1982,7 @@
 							t),
 				    vc->vc_scrl_erase_char,
 				    vc->vc_size_row * count);
-			return 1;
+			ret = 1;
 			break;
 
 		case SCROLL_WRAP_MOVE:
@@ -2044,10 +2052,13 @@
 							t),
 				    vc->vc_scrl_erase_char,
 				    vc->vc_size_row * count);
-			return 1;
+			ret = 1;
+			break;
 		}
+		break;
 	}
-	return 0;
+	vc->vc_video_erase_char = saved_ec;
+	return ret;
 }
 
 
@@ -2507,6 +2518,9 @@
 			c = vc->vc_video_erase_char;
 			vc->vc_video_erase_char =
 			    ((c & 0xfe00) >> 1) | (c & 0xff);
+			c = vc->vc_def_color;
+			vc->vc_scrl_erase_char =
+			    ((c & 0xFE00) >> 1) | (c & 0xFF);
 			vc->vc_attr >>= 1;
 		}
 	} else if (!vc->vc_hi_font_mask && cnt == 512) {
@@ -2537,9 +2551,14 @@
 			if (vc->vc_can_do_color) {
 				vc->vc_video_erase_char =
 				    ((c & 0xff00) << 1) | (c & 0xff);
+				c = vc->vc_def_color;
+				vc->vc_scrl_erase_char =
+				    ((c & 0xFF00) << 1) | (c & 0xFF);
 				vc->vc_attr <<= 1;
-			} else
+			} else {
 				vc->vc_video_erase_char = c & ~0x100;
+				vc->vc_scrl_erase_char = c & ~0x100;
+			}
 		}
 
 	}
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 93dca3e..7992b13 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -16,11 +16,10 @@
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/timer.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/upa.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -941,7 +940,7 @@
 	info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
 	info->pseudo_palette = par->pseudo_palette;
 
-	sbusfb_fill_var(&info->var, dp->node, 32);
+	sbusfb_fill_var(&info->var, dp, 32);
 	par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4);
 	ffb_fixup_var_rgb(&info->var);
 
@@ -987,7 +986,7 @@
 	 * chosen console, it will have video outputs off in
 	 * the DAC.
 	 */
-	ffb_blank(0, info);
+	ffb_blank(FB_BLANK_UNBLANK, info);
 
 	if (fb_alloc_cmap(&info->cmap, 256, 0))
 		goto out_unmap_dac;
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c
index cd9d4cc..aaef916 100644
--- a/drivers/video/geode/lxfb_ops.c
+++ b/drivers/video/geode/lxfb_ops.c
@@ -63,54 +63,32 @@
   { 0x00014284,  19688 },
   { 0x00011104,  20400 },
   { 0x00016363,  23625 },
-  { 0x00015303,  24380 },
   { 0x000031AC,  24923 },
   { 0x0000215D,  25175 },
   { 0x00001087,  27000 },
   { 0x0000216C,  28322 },
   { 0x0000218D,  28560 },
-  { 0x00010041,  29913 },
   { 0x000010C9,  31200 },
   { 0x00003147,  31500 },
-  { 0x000141A1,  32400 },
   { 0x000010A7,  33032 },
-  { 0x00012182,  33375 },
-  { 0x000141B1,  33750 },
   { 0x00002159,  35112 },
   { 0x00004249,  35500 },
   { 0x00000057,  36000 },
-  { 0x000141E1,  37125 },
   { 0x0000219A,  37889 },
   { 0x00002158,  39168 },
   { 0x00000045,  40000 },
-  { 0x000131A1,  40500 },
-  { 0x00010061,  42301 },
   { 0x00000089,  43163 },
-  { 0x00012151,  43875 },
   { 0x000010E7,  44900 },
   { 0x00002136,  45720 },
-  { 0x000152E1,  47250 },
-  { 0x00010071,  48000 },
   { 0x00003207,  49500 },
   { 0x00002187,  50000 },
-  { 0x00014291,  50625 },
-  { 0x00011101,  51188 },
-  { 0x00017481,  54563 },
   { 0x00004286,  56250 },
-  { 0x00014170,  57375 },
-  { 0x00016210,  58500 },
   { 0x000010E5,  60065 },
-  { 0x00013140,  62796 },
   { 0x00004214,  65000 },
-  { 0x00016250,  65250 },
   { 0x00001105,  68179 },
-  { 0x000141C0,  69600 },
-  { 0x00015220,  70160 },
-  { 0x00010050,  72000 },
   { 0x000031E4,  74250 },
   { 0x00003183,  75000 },
   { 0x00004284,  78750 },
-  { 0x00012130,  80052 },
   { 0x00001104,  81600 },
   { 0x00006363,  94500 },
   { 0x00005303,  97520 },
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index f3160fc..8bc46e9 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -16,10 +16,9 @@
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -562,7 +561,7 @@
 	par->physbase = op->resource[0].start;
 	par->which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-	sbusfb_fill_var(&info->var, dp->node, 32);
+	sbusfb_fill_var(&info->var, dp, 32);
 	leo_fixup_var_rgb(&info->var);
 
 	linebytes = of_getintprop_default(dp, "linebytes",
@@ -601,7 +600,7 @@
 	leo_init_wids(info);
 	leo_init_hw(info);
 
-	leo_blank(0, info);
+	leo_blank(FB_BLANK_UNBLANK, info);
 
 	if (fb_alloc_cmap(&info->cmap, 256, 0))
 		goto out_unmap_regs;
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 9de1c11..39ac49e 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -27,6 +27,16 @@
 	bool "Standard 224-color Linux logo"
 	default y
 
+config LOGO_BLACKFIN_VGA16
+	bool "16-colour Blackfin Processor Linux logo"
+	depends on BLACKFIN
+	default y
+
+config LOGO_BLACKFIN_CLUT224
+	bool "224-colour Blackfin Processor Linux logo"
+	depends on BLACKFIN
+	default y
+
 config LOGO_DEC_CLUT224
 	bool "224-color Digital Equipment Corporation Linux logo"
 	depends on MACH_DECSTATION || ALPHA
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
index a5fc4ed..b91251d 100644
--- a/drivers/video/logo/Makefile
+++ b/drivers/video/logo/Makefile
@@ -4,6 +4,8 @@
 obj-$(CONFIG_LOGO_LINUX_MONO)		+= logo_linux_mono.o
 obj-$(CONFIG_LOGO_LINUX_VGA16)		+= logo_linux_vga16.o
 obj-$(CONFIG_LOGO_LINUX_CLUT224)	+= logo_linux_clut224.o
+obj-$(CONFIG_LOGO_BLACKFIN_CLUT224)	+= logo_blackfin_clut224.o
+obj-$(CONFIG_LOGO_BLACKFIN_VGA16)	+= logo_blackfin_vga16.o
 obj-$(CONFIG_LOGO_DEC_CLUT224)		+= logo_dec_clut224.o
 obj-$(CONFIG_LOGO_MAC_CLUT224)		+= logo_mac_clut224.o
 obj-$(CONFIG_LOGO_PARISC_CLUT224)	+= logo_parisc_clut224.o
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index fc72684..2e85a2b 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -24,6 +24,8 @@
 extern const struct linux_logo logo_linux_mono;
 extern const struct linux_logo logo_linux_vga16;
 extern const struct linux_logo logo_linux_clut224;
+extern const struct linux_logo logo_blackfin_vga16;
+extern const struct linux_logo logo_blackfin_clut224;
 extern const struct linux_logo logo_dec_clut224;
 extern const struct linux_logo logo_mac_clut224;
 extern const struct linux_logo logo_parisc_clut224;
@@ -65,6 +67,10 @@
 		/* Generic Linux logo */
 		logo = &logo_linux_vga16;
 #endif
+#ifdef CONFIG_LOGO_BLACKFIN_VGA16
+		/* Blackfin processor logo */
+		logo = &logo_blackfin_vga16;
+#endif
 #ifdef CONFIG_LOGO_SUPERH_VGA16
 		/* SuperH Linux logo */
 		logo = &logo_superh_vga16;
@@ -76,6 +82,10 @@
 		/* Generic Linux logo */
 		logo = &logo_linux_clut224;
 #endif
+#ifdef CONFIG_LOGO_BLACKFIN_CLUT224
+		/* Blackfin Linux logo */
+		logo = &logo_blackfin_clut224;
+#endif
 #ifdef CONFIG_LOGO_DEC_CLUT224
 		/* DEC Linux logo on MIPS/MIPS64 or ALPHA */
 		logo = &logo_dec_clut224;
diff --git a/drivers/video/logo/logo_blackfin_clut224.ppm b/drivers/video/logo/logo_blackfin_clut224.ppm
new file mode 100644
index 0000000..dc9a50a
--- /dev/null
+++ b/drivers/video/logo/logo_blackfin_clut224.ppm
@@ -0,0 +1,1127 @@
+P3
+# This was generated by the GIMP & Netpbm tools
+# gimp linux_bf.svg (create 80x80 save as linux_bf.ppm)
+# pnmquant 224 linux_bf.ppm | pnmnoraw > logo_blackfin_clut224.ppm
+#
+80 80
+255
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+1 1 1  3 3 3  4 6 6  6 6 6  4 6 6  3 3 3
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  2 2 2  10 10 10  26 26 27
+44 44 45  66 66 66  78 81 81  78 81 81  75 75 76  60 60 60
+39 39 39  20 20 20  6 6 6  1 1 1  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  2 2 2  14 14 14  47 47 47  84 84 84  75 75 76
+47 47 47  12 12 12  0 0 0  0 0 0  0 0 0  20 20 20
+53 54 54  81 81 82  74 74 74  31 31 31  6 6 6  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+4 4 4  34 34 35  84 84 84  60 60 60  4 4 4  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  17 18 18  75 75 76  66 66 66  17 18 18
+1 1 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  3 3 3
+42 42 43  84 84 84  8 8 8  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 3 3  36 40 40  10 16 16  0 0 0  31 31 31  84 84 84
+29 29 30  2 2 2  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  1 1 1  26 27 27
+84 84 84  3 3 3  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+15 19 19  114 115 115  110 114 114  44 46 46  0 0 0  12 12 12
+90 87 86  24 24 24  1 1 1  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  8 8 8  75 75 76
+14 14 14  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+30 40 40  133 133 133  129 130 130  78 85 85  23 31 30  0 0 0
+19 19 19  78 81 81  13 13 13  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  26 27 27  81 81 82
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+36 40 40  89 90 91  55 63 63  23 31 30  4 6 6  0 0 0
+0 0 0  60 60 60  47 47 47  2 2 2  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  2 2 2  53 54 54  34 34 35
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+4 10 10  7 9 9  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  1 1 1  84 84 84  13 13 13  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  4 6 6  78 81 81  2 2 2
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  65 64 64  36 36 36  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 11 11  81 81 82  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  12 12 12  67 70 70  4 4 4  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  16 16 16  81 81 82  0 0 0
+0 0 0  0 0 0  4 10 10  44 50 50  18 21 21  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 1 1  78 85 85  120 121 122  7 9 9  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  82 82 81  12 12 12  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  19 19 19  81 81 82  0 0 0
+0 0 0  2 2 2  8 8 8  55 63 63  108 110 110  52 58 58
+0 0 0  0 0 0  0 0 0  0 0 0  42 42 43  129 130 130
+140 142 143  114 115 115  110 114 114  129 130 130  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  75 75 76  24 24 24  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  19 19 19  74 74 74  0 0 0
+4 6 6  167 168 167  196 196 197  196 196 197  61 65 66  78 85 85
+0 0 0  0 0 0  0 0 0  118 118 118  202 202 203  219 219 219
+219 219 219  214 214 215  187 187 188  78 85 85  29 33 34  0 0 0
+0 0 0  0 0 0  0 0 0  60 60 60  39 39 39  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  19 19 19  72 71 71  0 0 0
+185 185 184  244 245 245  250 251 252  251 251 252  247 248 249  36 36 36
+0 0 0  0 0 0  13 13 13  243 243 241  252 252 252  253 253 253
+253 253 253  252 252 252  247 247 246  193 193 194  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  42 42 43  50 51 51  1 1 1
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  19 19 19  78 81 81  0 0 0
+247 247 246  193 193 194  95 97 97  193 193 194  255 255 255  237 237 238
+0 0 0  0 0 0  202 202 203  255 255 255  247 247 246  108 107 107
+82 85 86  167 168 167  255 255 255  248 248 249  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  34 34 35  56 56 56  2 2 2
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  19 19 19  78 81 81  0 0 0
+250 250 251  50 51 51  153 154 155  150 151 151  244 245 245  244 245 245
+44 50 50  84 89 89  153 154 155  255 255 255  140 142 143  0 0 0
+149 149 150  156 155 156  237 237 238  254 254 254  67 70 70  0 0 0
+0 0 0  0 0 0  0 0 0  39 39 39  47 47 47  1 1 1
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  19 19 19  81 81 82  0 0 0
+248 248 249  34 34 35  72 71 71  165 165 165  202 202 203  244 245 245
+10 16 16  82 85 86  89 90 91  255 255 255  95 97 97  0 0 0
+0 0 0  53 54 54  177 177 174  255 255 255  127 127 126  0 0 0
+0 0 0  0 0 0  0 0 0  39 39 39  36 36 36  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  14 14 14  78 81 81  0 0 0
+243 243 243  89 90 91  0 0 0  36 40 40  201 147 55  241 205 27
+241 205 27  241 205 27  241 205 27  238 192 33  108 110 110  0 0 0
+0 0 0  0 0 0  191 190 190  254 254 254  34 34 35  0 0 0
+0 0 0  0 0 0  0 0 0  42 42 43  42 42 43  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  75 75 76  0 0 0
+202 202 203  218 217 217  21 19 17  230 165 41  199 129 48  213 157 40
+244 212 23  243 206 27  180 121 62  243 206 27  244 209 25  226 179 40
+15 10 7  103 103 103  254 254 254  251 251 252  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  17 18 18  58 58 58  2 2 2
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  9 9 9  84 84 84  0 0 0
+0 0 0  226 226 219  213 157 40  244 209 25  245 211 23  245 211 23
+245 214 38  245 214 38  245 211 23  245 211 23  245 211 23  244 212 23
+244 212 23  241 205 27  226 179 40  196 196 197  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  74 74 74  4 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  7 7 7  84 84 84  0 0 0
+54 42 32  213 157 40  243 206 27  245 211 23  245 211 23  245 211 23
+245 215 41  245 214 35  245 211 23  245 211 23  245 214 35  245 215 41
+245 214 35  245 211 23  245 211 23  238 204 29  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  81 81 82  12 12 12
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  4 6 6  74 74 74  0 0 0
+201 147 55  241 205 27  245 211 23  245 211 23  245 211 23  245 213 29
+245 214 38  245 211 23  245 211 23  245 214 35  245 215 41  245 215 41
+245 213 29  142 83 36  142 83 36  244 209 25  1 1 1  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  74 74 74  25 25 26
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  4 4 4  72 71 71  6 6 6
+213 157 40  244 209 25  245 211 23  245 211 23  245 211 23  245 213 29
+244 212 23  245 211 23  245 214 35  245 215 41  245 215 41  245 213 29
+142 83 36  142 83 36  238 192 33  241 205 27  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  44 44 44  49 50 50
+2 2 2  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  3 3 3  65 64 64  17 18 18
+199 129 48  199 129 48  245 211 23  245 211 23  245 211 23  245 211 23
+245 211 23  244 212 23  245 214 38  245 214 38  142 83 36  142 83 36
+142 83 36  245 211 23  244 210 23  230 165 41  0 0 0  0 0 0
+78 81 81  114 115 115  73 79 79  0 0 0  3 3 3  81 81 82
+9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  1 1 1  49 50 50  29 29 30
+90 87 86  199 129 48  173 101 51  173 101 51  245 211 23  245 211 23
+245 211 23  230 165 41  142 83 36  142 83 36  142 83 36  245 211 23
+244 210 23  241 205 27  230 165 41  175 173 165  3 3 3  0 0 0
+44 46 46  118 118 118  118 118 118  108 110 110  0 0 0  75 75 76
+28 28 28  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  1 1 1  52 53 53  26 26 27
+118 118 118  175 173 165  199 129 48  173 101 51  173 101 51  173 101 51
+173 101 51  142 83 36  173 101 51  245 211 23  244 209 25  238 204 29
+213 157 40  214 196 166  227 227 227  214 214 215  120 121 122  0 0 0
+0 0 0  108 110 110  118 118 118  118 118 118  0 0 0  23 23 23
+66 66 66  4 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  7 7 7  75 75 76  4 4 4
+127 127 126  205 205 205  181 181 181  199 129 48  226 179 40  244 209 25
+244 209 25  244 209 25  243 206 27  238 192 33  213 157 40  187 166 103
+234 234 234  248 248 249  251 252 252  248 248 249  214 214 215  0 0 0
+0 0 0  0 0 0  103 103 103  100 103 103  0 0 0  0 0 0
+78 81 81  24 24 24  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  26 27 27  82 82 81  0 0 0
+146 146 147  234 234 234  222 221 221  178 178 179  180 121 62  213 157 40
+213 157 40  213 157 40  201 147 55  180 121 62  219 219 219  243 243 241
+253 253 253  255 255 255  255 255 255  255 255 255  250 250 251  120 121 122
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+20 20 20  72 71 71  8 8 8  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  10 10 10  75 75 76  22 22 22  0 0 0
+205 205 205  253 253 253  247 248 249  212 211 212  178 178 179  161 161 162
+165 165 165  181 181 181  205 205 205  227 227 227  244 245 245  254 254 254
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  239 239 240
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  67 70 70  39 39 39  2 2 2  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  4 4 4  50 51 51  60 60 60  0 0 0  16 16 16
+249 250 251  255 255 255  255 255 255  240 240 240  209 210 210  193 193 194
+200 200 197  212 211 212  231 231 231  246 247 248  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  253 253 253
+153 154 155  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  3 3 3  84 84 84  20 20 20  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+2 2 2  33 33 34  81 81 82  0 0 0  0 0 0  231 231 231
+255 255 255  255 255 255  255 255 255  253 253 253  234 234 234  222 221 221
+227 227 227  237 237 238  250 250 251  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+240 240 240  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  26 27 27  72 71 71  8 8 8  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  1 1 1
+21 21 22  84 84 84  7 7 7  0 0 0  150 151 151  252 252 252
+255 255 255  255 255 255  255 255 255  255 255 255  252 252 252  244 245 245
+246 247 248  253 253 253  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+251 251 252  9 9 9  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  65 64 64  47 47 47  3 3 3
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  12 12 12
+75 75 76  26 26 27  0 0 0  1 1 1  239 239 240  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  202 202 203  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  84 84 84  28 28 29
+1 1 1  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  4 4 4  55 55 55
+60 60 60  0 0 0  0 0 0  95 97 97  248 248 249  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  244 245 245  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  14 14 14  82 82 81
+15 15 15  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  1 1 1  29 29 30  84 84 84
+0 0 0  0 0 0  0 0 0  156 155 156  247 247 246  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  247 247 246  240 240 240  232 232 233  232 232 233
+243 243 243  253 253 253  53 54 54  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  44 44 44
+60 60 60  6 6 6  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  10 10 10  81 81 82  14 14 14
+0 0 0  0 0 0  6 6 6  150 151 151  214 214 215  250 251 252
+255 255 255  255 255 255  255 255 255  246 247 248  218 217 217  214 214 215
+218 217 217  244 245 245  255 255 255  255 255 255  255 255 255  250 248 249
+232 232 233  214 214 215  196 196 197  182 183 184  181 181 181  181 181 181
+187 187 188  240 240 240  232 232 233  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+78 81 81  34 34 35  1 1 1  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  1 1 1  39 39 39  74 74 74  0 0 0
+0 0 0  0 0 0  60 60 60  161 161 162  200 200 197  229 229 230
+251 251 252  255 255 255  255 255 255  255 255 255  243 243 241  214 214 215
+248 248 249  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
+239 239 240  214 214 215  193 193 194  182 183 184  178 178 179  176 177 177
+176 177 177  182 183 184  248 248 249  14 14 14  0 0 0  61 65 66
+10 16 16  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+10 10 10  84 84 84  13 13 13  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  10 11 11  82 82 81  7 7 7  0 0 0
+0 0 0  0 0 0  165 165 165  229 229 230  249 250 251  254 254 254
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  253 253 253  240 240 240  227 227 227  205 205 205
+181 181 181  176 177 177  191 190 190  227 227 227  0 0 0  44 50 50
+84 89 89  61 65 66  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  58 58 58  49 50 50  3 3 3  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  1 1 1  36 36 36  66 66 66  0 0 0  29 33 34
+0 3 3  26 27 27  234 234 234  254 254 254  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+254 254 254  253 253 254  252 253 253  253 253 254  253 254 254  253 254 254
+254 254 254  255 255 255  255 255 255  255 255 255  255 255 255  251 251 252
+227 227 227  187 187 188  176 177 177  222 221 221  13 13 13  0 0 0
+12 15 14  73 79 79  36 40 40  0 0 0  0 0 0  0 0 0
+0 0 0  1 1 1  90 87 86  17 18 18  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  7 7 7  78 81 81  12 12 12  23 31 30  52 58 58
+0 0 0  209 210 210  253 253 253  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
+251 251 252  150 151 151  103 103 103  129 130 130  196 196 197  250 250 251
+252 252 253  254 254 254  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  240 240 240  193 193 194  196 196 197  229 229 230  0 0 0
+0 0 0  4 10 10  30 40 40  0 3 3  0 0 0  0 0 0
+0 0 0  0 0 0  47 47 47  53 54 54  3 3 3  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  23 23 23  81 81 82  0 0 0  52 58 58  36 40 40
+42 42 43  250 250 251  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
+227 227 227  7 7 7  7 7 7  7 7 7  7 7 7  44 44 45
+156 155 156  249 250 251  253 253 253  254 254 254  255 255 255  255 255 255
+255 255 255  255 255 255  247 247 246  222 221 221  239 239 240  0 0 0
+30 40 40  44 50 50  23 31 30  29 33 34  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  90 87 86  16 16 16  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+2 2 2  50 51 51  42 42 43  29 33 34  52 58 58  0 0 0
+232 232 233  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
+250 251 252  44 44 44  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  56 56 56  209 210 210  252 252 253  254 254 254  255 255 255
+255 255 255  255 255 255  255 255 255  254 253 253  249 250 251  146 146 147
+36 40 40  44 50 50  36 40 40  67 70 70  61 65 66  0 0 0
+0 0 0  0 0 0  0 0 0  55 55 55  44 44 45  1 1 1
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+10 10 10  81 81 82  1 1 1  52 58 58  44 50 50  52 53 53
+251 251 252  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  254 254 254
+253 253 253  187 187 188  8 8 8  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  19 19 19  178 178 179  252 252 253  254 254 254
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  237 237 238
+10 16 16  30 40 40  0 3 3  23 31 30  84 89 89  0 0 0
+0 0 0  0 0 0  0 0 0  3 3 3  81 81 82  9 9 9
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+29 29 30  72 71 71  10 16 16  52 58 58  0 0 0  222 221 221
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+254 254 254  251 251 252  95 97 97  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  10 10 10  161 161 162  251 252 252
+254 254 254  255 255 255  255 255 255  255 255 255  255 255 255  248 248 249
+0 0 0  0 0 0  0 0 0  0 0 0  84 89 89  0 3 3
+0 0 0  0 0 0  0 0 0  0 0 0  74 74 74  26 27 27
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  4 4 4
+65 64 64  20 20 20  20 25 25  30 40 40  0 0 0  247 247 246
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  253 253 254  222 221 221  9 9 9  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  8 8 8  149 149 150
+252 252 253  254 254 254  255 255 255  255 255 255  255 255 255  252 252 252
+0 0 0  0 0 0  0 0 0  0 0 0  73 79 79  12 15 14
+0 0 0  0 0 0  0 0 0  0 0 0  36 36 36  58 58 58
+3 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  20 20 20
+74 74 74  0 0 0  4 10 10  4 10 10  36 36 36  252 252 252
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  227 227 227  253 253 253  255 255 255
+255 255 255  254 254 254  250 251 252  65 64 64  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  8 8 8
+146 146 147  251 252 252  254 254 254  255 255 255  255 255 255  253 254 254
+0 0 0  0 0 0  0 0 0  0 0 0  52 58 58  10 16 16
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  82 82 81
+9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  4 6 6  65 64 64
+25 25 25  0 3 3  30 40 40  0 0 0  187 187 188  254 254 254
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  193 193 194  253 252 252  255 255 255
+255 255 255  255 255 255  252 253 253  129 130 130  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+8 8 8  149 149 150  252 252 253  254 254 254  255 255 255  254 254 254
+52 53 53  0 0 0  0 0 0  0 0 0  20 25 25  2 5 4
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  81 81 82
+20 20 20  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  26 26 27  81 81 82
+0 0 0  18 21 21  73 79 79  0 0 0  237 237 238  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  182 183 184  255 255 255  255 255 255
+255 255 255  255 255 255  253 253 253  176 177 177  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  8 8 8  153 154 155  251 252 252  254 254 254  255 255 255
+150 151 151  0 0 0  0 0 0  0 0 0  20 25 25  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  65 64 64
+33 33 34  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  6 6 6  67 70 70  20 20 20
+0 0 0  23 31 30  82 85 86  0 0 0  247 247 246  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  182 183 184  255 255 255  255 255 255
+255 255 255  255 255 255  253 254 254  214 214 215  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  8 8 8  156 155 156  252 252 253  254 254 254
+167 168 167  0 0 0  0 0 0  0 0 0  67 70 70  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  47 47 47
+44 44 44  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  21 21 22  75 75 76  0 0 0
+0 0 0  29 33 34  84 89 89  0 0 0  248 248 249  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  248 248 249  181 181 181  255 255 255  255 255 255
+255 255 255  255 255 255  254 254 254  240 240 240  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  8 8 8  161 161 162  251 252 252
+185 185 184  4 4 4  0 0 0  10 11 11  100 103 103  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  36 36 36
+55 55 55  2 2 2  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  33 33 34  50 51 51  0 0 0
+0 0 0  9 11 11  82 85 86  10 16 16  248 248 249  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  245 244 245  179 180 181  255 255 255  255 255 255
+255 255 255  255 255 255  254 254 254  251 252 252  20 20 20  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  10 10 10  161 161 162
+205 205 205  17 18 18  0 0 0  95 97 97  78 81 81  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  36 36 36
+53 54 54  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  31 31 31  58 58 58  0 0 0
+0 0 0  0 0 0  67 70 70  78 81 81  248 248 249  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  234 234 234  179 180 181  255 255 255  255 255 255
+255 255 255  255 255 255  254 254 254  251 252 252  23 23 23  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+10 11 11  84 84 84  161 161 162  209 210 210  229 229 230  237 237 238
+202 202 203  26 26 27  9 11 11  44 50 50  0 0 0  4 6 6
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  52 53 53
+39 39 39  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  23 23 23  78 81 81  213 157 40
+243 206 27  243 206 27  54 42 32  73 79 79  222 221 221  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  238 238 236  178 178 179  255 255 255  255 255 255
+255 255 255  255 255 255  254 254 254  251 252 253  36 36 36  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  84 84 84
+222 221 221  251 252 252  252 253 253  253 253 253  253 254 254  252 252 253
+146 146 147  140 142 143  156 155 156  110 114 114  26 27 27  82 85 86
+84 89 89  95 97 97  36 40 40  0 0 0  0 0 0  74 74 74
+23 23 23  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  2 2 2  14 14 14
+24 24 24  26 26 27  26 26 27  26 26 27  25 25 26  21 21 22
+7 7 7  0 0 0  1 1 1  34 34 35  238 192 33  244 210 23
+244 212 23  244 212 23  244 210 23  88 79 47  200 200 197  254 254 254
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  244 245 245  179 180 181  255 255 255  255 255 255
+255 255 255  255 255 255  254 254 254  252 252 253  36 36 36  7 7 7
+7 7 7  7 7 7  7 7 7  8 8 8  149 149 150  251 251 252
+252 252 253  253 253 253  253 253 253  250 248 249  239 223 156  239 223 156
+120 121 122  182 183 184  176 177 177  120 121 122  33 33 34  3 3 3
+0 0 0  67 70 70  146 146 147  20 25 25  1 1 1  82 82 81
+9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  19 19 19  89 90 91
+146 146 147  150 151 151  150 151 151  150 151 151  150 151 151  129 130 130
+58 58 58  6 6 6  14 14 14  201 147 55  245 211 23  245 213 29
+245 214 35  245 215 41  245 213 29  244 210 23  142 83 36  232 232 233
+254 254 254  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  185 185 184  255 255 255  255 255 255
+255 255 255  255 255 255  254 254 254  251 252 252  50 51 51  7 7 7
+7 7 7  7 7 7  7 7 7  146 146 147  251 252 252  252 253 253
+251 252 253  239 239 240  171 168 154  129 130 130  137 136 134  175 173 165
+221 218 200  65 64 64  22 22 22  186 186 187  114 115 115  26 26 27
+2 2 2  0 0 0  61 65 66  31 33 27  238 192 33  108 96 91
+9 9 9  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  2 2 2  52 53 53  178 178 179
+21 21 22  7 7 7  7 7 7  7 7 7  7 7 7  118 118 118
+137 136 134  36 36 36  65 64 64  243 206 27  244 212 23  245 215 41
+245 215 41  245 215 41  245 215 41  244 209 25  244 209 25  1 1 1
+219 219 219  253 253 253  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  214 214 215  255 255 255  255 255 255
+255 255 255  255 255 255  254 254 254  252 252 253  50 51 51  7 7 7
+7 7 7  7 7 7  84 84 84  250 251 252  252 253 253  251 251 252
+167 168 167  22 22 22  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  34 34 35  187 187 188  103 103 103
+29 29 30  3 3 3  7 9 9  238 204 29  245 215 41  245 214 35
+28 28 28  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  7 7 7  90 87 86  178 178 179
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  16 16 16
+193 193 194  133 133 133  187 166 103  245 218 76  245 218 76  245 216 51
+245 216 51  245 218 76  246 224 96  245 218 76  245 218 76  245 218 76
+25 25 25  186 186 187  252 252 252  254 254 254  254 254 254  253 254 254
+254 254 254  254 254 254  254 254 254  246 247 248  254 254 254  253 254 254
+254 254 254  254 254 254  253 254 254  251 252 252  36 36 36  7 7 7
+7 7 7  20 20 20  229 229 230  253 253 253  252 253 253  178 178 179
+10 10 10  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  42 42 43  196 196 197
+118 118 118  33 33 34  238 204 29  245 215 41  245 215 41  245 215 41
+49 50 50  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  17 18 18  120 121 122  137 136 134
+7 7 7  7 7 7  34 34 35  20 20 20  7 7 7  7 7 7
+202 202 203  209 206 202  193 187 162  193 187 162  248 234 156  245 218 76
+245 218 76  248 234 156  193 187 162  193 187 162  193 187 162  214 196 166
+240 219 129  95 97 97  196 196 197  186 186 187  187 187 188  196 196 197
+252 252 253  251 252 253  212 211 212  187 187 188  196 196 197  251 252 252
+218 217 217  187 187 188  191 190 190  250 251 252  24 24 24  7 7 7
+7 7 7  110 114 114  252 252 253  253 254 254  250 251 252  89 90 91
+89 90 91  129 130 130  127 127 126  44 44 44  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  49 50 50
+202 202 203  214 196 166  245 216 51  245 214 38  245 214 35  245 214 38
+58 58 58  2 2 2  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  31 31 31  156 155 156  82 82 81
+7 7 7  10 10 10  237 237 238  66 66 66  7 7 7  25 25 25
+247 248 249  81 81 82  7 7 7  31 31 31  247 237 174  245 218 76
+246 226 108  200 200 197  7 7 7  7 7 7  7 7 7  137 136 134
+247 237 174  193 193 194  72 71 71  7 7 7  7 7 7  8 8 8
+196 196 197  250 251 252  67 70 70  7 7 7  84 84 84  244 245 245
+47 47 47  7 7 7  118 118 118  249 250 251  12 12 12  7 7 7
+9 9 9  218 217 217  253 253 253  254 254 254  252 253 253  251 251 252
+249 250 251  237 237 238  95 97 97  9 9 9  15 15 15  95 97 97
+47 47 47  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+66 66 66  240 230 197  246 226 108  245 214 38  245 211 23  244 212 23
+65 64 64  3 3 3  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  2 2 2  52 53 53  185 185 184  25 25 25
+7 7 7  60 60 60  240 240 240  14 14 14  7 7 7  84 84 84
+247 248 249  23 23 23  7 7 7  94 91 88  248 234 156  245 218 76
+248 234 156  127 127 126  7 7 7  7 7 7  7 7 7  167 168 167
+251 248 240  65 64 64  7 7 7  7 7 7  7 7 7  7 7 7
+84 84 84  243 243 243  15 15 15  7 7 7  140 142 143  146 146 147
+7 7 7  33 33 34  237 237 238  243 243 243  21 21 22  120 121 122
+218 217 217  252 252 253  254 254 254  253 253 254  252 253 253  251 252 252
+247 248 249  72 71 71  7 7 7  58 58 58  222 221 221  248 248 249
+75 75 76  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  82 82 81  246 239 193  246 226 108  245 216 51  245 214 38
+238 192 33  21 21 22  1 1 1  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  8 8 8  90 87 86  182 183 184  7 7 7
+7 7 7  120 121 122  187 187 188  7 7 7  7 7 7  146 146 147
+205 205 205  7 7 7  7 7 7  153 153 148  240 219 129  246 224 96
+246 239 193  39 39 39  60 60 60  108 110 110  7 7 7  202 202 203
+227 227 227  7 7 7  7 7 7  205 205 205  89 90 91  7 7 7
+120 121 122  193 193 194  7 7 7  7 7 7  186 186 187  25 25 25
+7 7 7  167 168 167  251 251 252  243 243 243  214 214 215  250 251 252
+251 252 253  254 254 254  253 253 253  219 219 219  140 140 139  140 140 139
+118 118 118  7 7 7  52 53 53  237 237 238  247 247 246  176 177 177
+8 8 8  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  95 97 97  246 239 193  246 226 108  245 216 51
+245 214 38  201 147 55  31 31 31  103 103 103  103 103 103  72 71 71
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  17 18 18  127 127 126  140 140 139  7 7 7
+7 7 7  17 18 18  17 18 18  7 7 7  95 97 97  244 245 245
+146 146 147  7 7 7  7 7 7  200 200 197  246 226 108  240 219 129
+194 194 184  7 7 7  140 140 139  89 90 91  7 7 7  232 232 233
+165 165 165  7 7 7  31 31 31  249 250 251  39 39 39  7 7 7
+176 177 177  133 133 133  7 7 7  22 22 22  108 110 110  7 7 7
+72 71 71  251 252 252  252 253 253  250 251 252  247 248 249  205 205 205
+251 252 253  254 254 254  252 252 253  84 84 84  7 7 7  7 7 7
+7 7 7  7 7 7  140 142 143  247 248 249  140 140 139  14 14 14
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  16 16 16
+14 14 14  7 7 7  7 7 7  114 115 115  246 239 193  246 224 96
+245 216 51  245 216 51  243 235 220  176 177 177  185 185 184  229 229 230
+47 47 47  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  31 31 31  156 155 156  90 87 86  7 7 7
+7 7 7  7 7 7  7 7 7  31 31 31  243 243 241  247 247 246
+84 84 84  7 7 7  26 27 27  246 239 193  246 226 108  248 234 156
+108 110 110  7 7 7  212 211 212  44 44 44  22 22 22  249 250 251
+108 107 107  7 7 7  89 90 91  238 238 236  114 115 115  118 118 118
+231 231 231  75 75 76  7 7 7  34 34 35  10 11 11  12 12 12
+214 214 215  253 253 253  253 253 253  200 200 197  31 31 31  103 103 103
+252 252 253  252 253 253  218 217 217  9 9 9  7 7 7  7 7 7
+7 7 7  7 7 7  25 25 25  39 39 39  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  103 103 103  234 234 234
+181 181 181  7 7 7  7 7 7  7 7 7  133 133 133  247 237 174
+246 224 96  246 226 108  185 185 184  177 177 174  153 154 155  181 181 181
+140 140 139  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  1 1 1  49 50 50  186 186 187  28 28 28  7 7 7
+12 12 12  22 22 22  7 7 7  7 7 7  108 107 107  247 247 246
+25 25 25  7 7 7  90 87 86  247 237 174  246 226 108  246 239 193
+28 28 28  44 44 44  237 237 238  9 9 9  53 54 54  249 250 251
+49 50 50  7 7 7  153 153 148  249 241 199  214 196 166  185 185 184
+229 229 230  19 19 19  7 7 7  7 7 7  7 7 7  103 103 103
+251 252 253  254 254 254  253 253 253  150 151 151  7 7 7  187 187 188
+252 252 253  251 251 252  103 103 103  7 7 7  7 7 7  7 7 7
+7 7 7  23 23 23  17 18 18  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  12 12 12  153 153 148  246 239 193  249 241 199
+161 161 162  9 9 9  84 84 84  108 110 110  25 25 25  153 153 148
+247 237 174  246 224 96  218 217 217  165 165 165  182 183 184  193 193 194
+114 115 115  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  4 4 4  74 74 74  181 181 181  7 7 7  7 7 7
+110 114 114  200 200 197  7 7 7  7 7 7  60 60 60  209 210 210
+7 7 7  7 7 7  146 146 147  248 234 156  248 234 156  177 177 174
+7 7 7  118 118 118  193 193 194  7 7 7  84 84 84  232 232 233
+8 8 8  7 7 7  209 210 210  221 218 200  193 187 162  219 219 219
+200 200 197  7 7 7  7 7 7  7 7 7  7 7 7  95 97 97
+251 252 252  254 254 254  252 253 253  118 118 118  29 29 30  247 248 249
+252 252 253  227 227 227  16 16 16  7 7 7  7 7 7  7 7 7
+100 103 103  218 217 217  219 218 214  7 7 7  7 7 7  7 7 7
+7 7 7  21 21 22  185 185 184  246 239 193  248 234 156  240 230 197
+60 60 60  194 194 184  246 239 193  249 241 199  137 136 134  10 10 10
+171 168 154  248 234 156  248 234 156  226 226 219  209 210 210  249 241 199
+28 28 28  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  13 13 13  108 110 110  146 146 147  7 7 7  7 7 7
+167 168 167  140 140 139  7 7 7  7 7 7  120 121 122  146 146 147
+7 7 7  7 7 7  194 194 184  240 219 129  247 237 174  95 97 97
+7 7 7  95 97 97  90 87 86  7 7 7  118 118 118  176 177 177
+7 7 7  28 28 28  248 248 249  44 44 45  7 7 7  167 168 167
+140 140 139  7 7 7  36 36 36  74 74 74  7 7 7  65 64 64
+251 252 253  254 254 254  251 252 252  81 81 82  108 110 110  251 252 252
+251 251 252  127 127 126  7 7 7  7 7 7  8 8 8  140 140 139
+181 181 181  140 140 139  221 218 200  7 7 7  7 7 7  7 7 7
+34 34 35  209 210 210  231 231 231  246 239 193  247 237 174  194 194 184
+227 227 227  249 241 199  240 219 129  248 234 156  153 153 148  7 7 7
+13 13 13  185 185 184  248 234 156  245 218 76  245 216 51  245 214 38
+31 31 31  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  31 31 31  153 154 155  89 90 91  7 7 7  8 8 8
+232 232 233  82 82 81  7 7 7  7 7 7  179 180 181  89 90 91
+7 7 7  24 24 24  243 235 220  248 234 156  240 230 197  20 20 20
+7 7 7  7 7 7  7 7 7  7 7 7  149 149 150  118 118 118
+7 7 7  90 87 86  229 229 230  7 7 7  7 7 7  229 229 230
+82 82 81  7 7 7  95 97 97  100 103 103  7 7 7  34 34 35
+251 252 252  253 253 254  251 251 252  47 47 47  193 193 194  251 252 252
+239 239 240  23 23 23  7 7 7  13 13 13  165 165 165  234 234 234
+149 149 150  146 114 101  200 200 197  7 7 7  7 7 7  52 53 53
+227 227 227  167 168 167  16 16 16  214 196 166  248 234 156  243 235 220
+219 219 219  156 155 156  247 237 174  246 239 193  75 75 76  7 7 7
+60 60 60  227 227 227  243 235 220  240 219 129  245 218 76  245 213 29
+16 16 16  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+1 1 1  49 50 50  185 185 184  33 33 34  7 7 7  10 11 11
+56 56 56  16 16 16  7 7 7  10 10 10  237 237 238  26 27 27
+7 7 7  55 55 55  185 185 184  221 218 200  167 168 167  7 7 7
+20 20 20  39 39 39  10 11 11  7 7 7  181 181 181  58 58 58
+7 7 7  103 103 103  133 133 133  7 7 7  44 44 44  247 248 249
+24 24 24  7 7 7  156 155 156  129 130 130  7 7 7  9 9 9
+244 245 245  252 253 253  237 237 238  34 34 35  248 248 249  251 251 252
+161 161 162  7 7 7  24 24 24  187 187 188  212 211 212  67 70 70
+187 187 188  173 170 143  209 206 202  10 10 10  95 97 97  237 237 238
+129 130 130  8 8 8  89 90 91  246 239 193  247 237 174  177 177 174
+17 18 18  137 136 134  249 241 199  219 218 214  10 10 10  95 97 97
+243 243 243  150 151 151  31 31 31  221 218 200  240 219 129  53 54 54
+3 3 3  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+4 4 4  72 71 71  182 183 184  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  12 12 12  161 161 162  209 210 210  7 7 7
+7 7 7  7 7 7  7 7 7  187 187 188  82 82 81  7 7 7
+146 146 147  247 248 249  17 18 18  7 7 7  212 211 212  47 47 47
+7 7 7  7 7 7  7 7 7  8 8 8  146 146 147  205 205 205
+7 7 7  7 7 7  214 214 215  156 155 156  7 7 7  7 7 7
+218 217 217  251 252 252  186 186 187  110 114 114  249 250 251  248 248 249
+75 75 76  34 34 35  205 205 205  129 130 130  16 16 16  7 7 7
+156 155 156  214 196 166  240 230 197  243 243 241  227 227 227  74 74 74
+7 7 7  29 29 30  226 226 219  249 241 199  175 173 165  14 14 14
+9 9 9  221 218 200  246 239 193  153 153 148  146 146 147  246 247 248
+110 114 114  7 7 7  7 7 7  42 42 43  193 193 194  95 97 97
+19 19 19  1 1 1  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+6 6 6  84 84 84  140 142 143  7 7 7  7 7 7  7 7 7
+7 7 7  20 20 20  177 177 174  249 241 199  149 149 150  7 7 7
+7 7 7  7 7 7  10 11 11  226 226 219  13 13 13  8 8 8
+219 218 214  219 218 214  7 7 7  8 8 8  238 238 236  200 200 197
+13 13 13  7 7 7  13 13 13  161 161 162  243 235 220  146 146 147
+7 7 7  29 29 30  232 232 233  176 177 177  7 7 7  7 7 7
+182 183 184  237 237 238  129 130 130  167 168 167  176 177 177  202 202 203
+10 11 11  95 97 97  44 44 45  7 7 7  7 7 7  7 7 7
+75 75 76  226 226 219  243 235 220  156 155 156  24 24 24  7 7 7
+7 7 7  176 177 177  247 247 246  200 200 197  17 18 18  7 7 7
+49 50 50  246 239 193  248 234 156  251 248 240  239 239 240  84 84 84
+7 7 7  7 7 7  7 7 7  7 7 7  60 60 60  187 187 188
+84 84 84  14 14 14  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+4 4 4  53 54 54  137 136 134  156 155 156  161 161 162  161 161 162
+167 168 167  239 223 156  240 219 129  246 226 108  239 223 156  239 223 156
+239 223 156  239 223 156  214 196 166  239 223 156  193 187 162  193 187 162
+248 234 156  239 223 156  193 187 162  193 187 162  248 234 156  248 234 156
+214 196 166  193 187 162  214 196 166  248 234 156  240 219 129  214 196 166
+193 187 162  193 187 162  171 168 154  146 146 147  137 136 134  137 136 134
+161 161 162  209 210 210  65 64 64  202 202 203  179 180 181  140 140 139
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  60 60 60  39 39 39  7 7 7  7 7 7  7 7 7
+66 66 66  249 250 251  202 202 203  16 16 16  7 7 7  7 7 7
+23 23 23  243 235 220  246 239 193  226 226 219  52 53 53  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  75 75 76
+176 177 177  66 66 66  9 9 9  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  10 10 10  28 28 29  34 34 35  36 36 36  36 36 36
+44 44 45  146 114 101  241 207 50  241 207 50  241 207 50  241 211 63
+241 211 63  241 211 63  241 211 63  241 211 63  241 211 63  245 216 51
+245 216 51  245 216 51  241 211 63  241 211 63  245 216 51  241 211 63
+245 218 76  245 218 76  245 216 51  245 215 41  245 214 38  241 207 50
+241 211 63  201 147 55  88 79 47  29 29 30  34 34 35  42 42 43
+103 103 103  191 190 190  75 75 76  196 196 197  200 200 197  65 64 64
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+90 87 86  146 146 147  19 19 19  7 7 7  7 7 7  7 7 7
+7 7 7  90 87 86  140 140 139  31 31 31  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+103 103 103  161 161 162  53 54 54  7 7 7  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  12 12 12  50 51 51  146 114 101  180 121 62  199 129 48
+201 147 55  213 157 40  213 157 40  230 165 41  226 179 40  226 179 40
+238 192 33  241 205 27  244 209 25  244 210 23  244 212 23  245 211 23
+245 211 23  245 211 23  245 211 23  244 209 25  238 204 29  226 179 40
+213 157 40  199 129 48  54 42 32  0 0 0  4 6 6  44 44 45
+150 151 151  129 130 130  137 136 134  205 205 205  202 202 203  8 8 8
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  129 130 130  146 146 147  47 47 47  4 4 4  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  2 2 2  12 12 12  28 28 29  49 50 50
+74 74 74  108 96 91  180 121 62  180 121 62  199 129 48  201 147 55
+213 157 40  230 165 41  226 179 40  238 192 33  241 205 27  241 205 27
+243 206 27  243 206 27  241 205 27  238 204 29  226 179 40  213 157 40
+199 129 48  199 129 48  21 19 17  65 64 64  103 103 103  167 168 167
+202 202 203  24 24 24  193 193 194  229 229 230  140 140 139  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  8 8 8  156 155 156  133 133 133  36 36 36  3 3 3
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  1 1 1
+4 4 4  10 11 11  21 21 22  39 39 39  60 60 60  108 96 91
+180 121 62  199 129 48  199 129 48  213 157 40  230 165 41  226 179 40
+226 179 40  226 179 40  226 179 40  226 179 40  213 157 40  199 129 48
+180 121 62  99 91 79  72 71 71  56 56 56  129 130 130  167 168 167
+21 21 22  17 18 18  231 231 231  229 229 230  52 53 53  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  13 13 13  176 177 177  120 121 122  33 33 34
+2 2 2  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  2 2 2  8 8 8
+21 21 22  47 47 47  99 91 79  180 121 62  199 129 48  199 129 48
+201 147 55  213 157 40  213 157 40  201 147 55  199 129 48  180 121 62
+99 91 79  26 26 27  9 9 9  60 60 60  186 186 187  31 31 31
+7 7 7  60 60 60  243 243 243  209 210 210  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  7 7 7  7 7 7  7 7 7
+7 7 7  7 7 7  7 7 7  26 27 27  193 193 194  108 110 110
+22 22 22  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  1 1 1  8 8 8  24 24 24  58 58 58  108 96 91
+180 121 62  180 121 62  180 121 62  180 121 62  180 121 62  72 71 71
+15 15 15  0 0 0  4 6 6  75 75 76  156 155 156  24 24 24
+24 24 24  108 107 107  232 232 233  137 136 134  24 24 24  24 24 24
+24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
+24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
+24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
+24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
+24 24 24  24 24 24  24 24 24  24 24 24  24 24 24  24 24 24
+24 24 24  24 24 24  24 24 24  24 24 24  58 58 58  176 177 177
+60 60 60  3 3 3
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  2 2 2  12 12 12
+26 27 27  44 44 44  55 55 55  50 51 51  29 29 30  8 8 8
+0 0 0  0 0 0  3 3 3  47 47 47  127 127 126  150 151 151
+150 151 151  140 142 143  129 130 130  140 142 143  150 151 151  150 151 151
+150 151 151  150 151 151  150 151 151  150 151 151  150 151 151  150 151 151
+150 151 151  150 151 151  153 154 155  161 161 162  165 165 165  167 168 167
+177 177 174  167 168 167  161 161 162  156 155 156  150 151 151  150 151 151
+150 151 151  150 151 151  150 151 151  150 151 151  150 151 151  150 151 151
+150 151 151  150 151 151  150 151 151  150 151 151  150 151 151  150 151 151
+150 151 151  150 151 151  150 151 151  150 151 151  149 149 150  127 127 126
+44 44 45  2 2 2
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  2 2 2  1 1 1  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  7 7 7  21 21 22  25 25 26
+25 25 26  24 24 24  20 20 20  23 23 24  25 25 26  26 26 27
+26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 26 27
+26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 27 27
+28 28 29  26 27 27  26 26 27  26 26 27  26 26 27  26 26 27
+26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 26 27
+26 26 27  26 26 27  26 26 27  26 26 27  26 26 27  26 26 27
+26 26 27  26 26 27  26 26 27  26 26 27  25 25 26  21 21 22
+7 7 7  0 0 0
diff --git a/drivers/video/logo/logo_blackfin_vga16.ppm b/drivers/video/logo/logo_blackfin_vga16.ppm
new file mode 100644
index 0000000..1352b02
--- /dev/null
+++ b/drivers/video/logo/logo_blackfin_vga16.ppm
@@ -0,0 +1,1127 @@
+P3
+# This was generated by the GIMP & Netpbm tools
+# gimp linux_bf.svg (create 80x80 save as linux_bf.ppm)
+# ppmquant -mapfile clut_vga16.ppm linux_bf.ppm | pnmnoraw > logo_blackfin_vga16.ppm
+#
+80 80
+255
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  85 85 85  85 85 85  85 85 85  85 85 85  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
+170 170 170  85 85 85  85 85 85  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  170 170 170  170 170 170  170 170 170  85 85 85  85 85 85
+0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  255 255 255
+255 255 255  255 255 255  170 170 170  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  0 0 0
+0 0 0  0 0 0  0 0 0  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+255 255 255  170 170 170  85 85 85  170 170 170  255 255 255  255 255 255
+0 0 0  0 0 0  170 170 170  255 255 255  255 255 255  85 85 85
+85 85 85  170 170 170  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+255 255 255  85 85 85  170 170 170  170 170 170  255 255 255  255 255 255
+85 85 85  85 85 85  170 170 170  255 255 255  170 170 170  0 0 0
+170 170 170  170 170 170  255 255 255  255 255 255  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+255 255 255  0 0 0  85 85 85  170 170 170  170 170 170  255 255 255
+0 0 0  85 85 85  85 85 85  255 255 255  85 85 85  0 0 0
+0 0 0  85 85 85  170 170 170  255 255 255  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+255 255 255  85 85 85  0 0 0  0 0 0  255 85 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  85 85 85  0 0 0
+0 0 0  0 0 0  170 170 170  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+170 170 170  255 255 255  0 0 0  255 85 85  170 85 0  170 85 0
+255 255 85  255 255 85  170 85 0  255 255 85  255 255 85  255 255 85
+0 0 0  85 85 85  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  255 255 255  255 85 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  255 85 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+170 85 0  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  170 85 0  85 85 85  255 255 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+255 85 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+170 85 0  85 85 85  255 255 85  255 255 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+170 85 0  170 85 0  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  170 85 0  170 85 0
+170 85 0  255 255 85  255 255 85  255 85 85  0 0 0  0 0 0
+85 85 85  85 85 85  85 85 85  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+85 85 85  170 85 0  170 85 0  170 85 0  255 255 85  255 255 85
+255 255 85  255 85 85  170 85 0  170 85 0  170 85 0  255 255 85
+255 255 85  255 255 85  255 85 85  170 170 170  0 0 0  0 0 0
+85 85 85  85 85 85  85 85 85  85 85 85  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+85 85 85  170 170 170  170 85 0  170 85 0  170 85 0  170 85 0
+170 85 0  170 85 0  170 85 0  255 255 85  255 255 85  255 255 85
+255 85 85  170 170 170  255 255 255  255 255 255  85 85 85  0 0 0
+0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+170 170 170  170 170 170  170 170 170  170 85 0  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 85 85  170 170 170
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  0 0 0
+0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+170 170 170  255 255 255  255 255 255  170 170 170  170 85 0  255 85 85
+255 85 85  255 85 85  255 85 85  255 85 85  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+170 170 170  255 255 255  255 255 255  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  170 170 170  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
+255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
+170 170 170  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  170 170 170  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+85 85 85  0 0 0  0 0 0  85 85 85  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  85 85 85  170 170 170  170 170 170  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  255 255 255  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  170 170 170  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
+170 170 170  170 170 170  170 170 170  255 255 255  0 0 0  85 85 85
+85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  170 170 170  170 170 170  255 255 255  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  0 0 0  85 85 85
+0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  170 170 170  85 85 85  170 170 170  170 170 170  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  170 170 170  170 170 170  255 255 255  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  85 85 85  0 0 0
+0 0 0  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  85 85 85  0 0 0
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
+0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  85 85 85  85 85 85  85 85 85
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  85 85 85  0 0 0  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+170 170 170  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  170 170 170  255 255 255  255 255 255  255 255 255
+170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
+170 170 170  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
+170 170 170  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
+170 170 170  0 0 0  0 0 0  85 85 85  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  0 0 0
+0 0 0  0 0 0  85 85 85  85 85 85  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  170 170 170  255 255 255  255 255 255
+170 170 170  0 0 0  0 0 0  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 85 0
+255 255 85  255 255 85  0 0 0  85 85 85  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+170 170 170  170 170 170  170 170 170  85 85 85  0 0 0  85 85 85
+85 85 85  85 85 85  0 0 0  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  85 85 85  170 170 170  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 85  170 170 170
+85 85 85  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+85 85 85  0 0 0  0 0 0  170 85 0  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  170 85 0  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
+255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
+255 255 255  85 85 85  0 0 0  170 170 170  85 85 85  0 0 0
+0 0 0  0 0 0  85 85 85  0 0 0  255 255 85  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+170 170 170  0 0 0  85 85 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  0 0 0
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  85 85 85  0 0 0
+0 0 0  0 0 0  85 85 85  255 255 255  255 255 255  255 255 255
+170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  0 0 0  0 0 0  255 255 85  255 255 85  255 255 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+170 170 170  170 170 170  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  0 0 0  0 0 0
+0 0 0  0 0 0  255 255 255  255 255 255  255 255 255  170 170 170
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  170 170 170
+85 85 85  0 0 0  255 255 85  255 255 85  255 255 85  255 255 85
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+170 170 170  170 170 170  170 170 170  170 170 170  255 255 85  255 255 85
+255 255 85  255 255 85  170 170 170  170 170 170  170 170 170  170 170 170
+255 255 85  85 85 85  170 170 170  170 170 170  170 170 170  170 170 170
+255 255 255  255 255 255  170 170 170  170 170 170  170 170 170  255 255 255
+255 255 255  170 170 170  170 170 170  255 255 255  0 0 0  0 0 0
+0 0 0  85 85 85  255 255 255  255 255 255  255 255 255  85 85 85
+85 85 85  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+170 170 170  170 170 170  255 255 85  255 255 85  255 255 85  255 255 85
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  0 0 0  255 255 255  85 85 85  0 0 0  0 0 0
+255 255 255  85 85 85  0 0 0  0 0 0  255 255 255  255 255 85
+255 255 85  170 170 170  0 0 0  0 0 0  0 0 0  170 170 170
+255 255 255  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
+170 170 170  255 255 255  85 85 85  0 0 0  85 85 85  255 255 255
+85 85 85  0 0 0  85 85 85  255 255 255  0 0 0  0 0 0
+0 0 0  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  85 85 85
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  255 255 255  255 255 85  255 255 85  255 255 85  255 255 85
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
+0 0 0  85 85 85  255 255 255  0 0 0  0 0 0  85 85 85
+255 255 255  0 0 0  0 0 0  85 85 85  255 255 85  255 255 85
+255 255 85  85 85 85  0 0 0  0 0 0  0 0 0  170 170 170
+255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  255 255 255  0 0 0  0 0 0  170 170 170  170 170 170
+0 0 0  0 0 0  255 255 255  255 255 255  0 0 0  85 85 85
+255 255 255  255 255 255  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  85 85 85  0 0 0  85 85 85  255 255 255  255 255 255
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  255 255 255  255 255 85  255 255 85  255 255 85
+255 255 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
+0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  170 170 170
+170 170 170  0 0 0  0 0 0  170 170 170  255 255 85  255 255 85
+255 255 255  0 0 0  85 85 85  85 85 85  0 0 0  170 170 170
+255 255 255  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
+85 85 85  170 170 170  0 0 0  0 0 0  170 170 170  0 0 0
+0 0 0  170 170 170  255 255 255  255 255 255  255 255 255  255 255 255
+255 255 255  255 255 255  255 255 255  255 255 255  170 170 170  170 170 170
+85 85 85  0 0 0  85 85 85  255 255 255  255 255 255  170 170 170
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  255 255 255  255 255 85  255 255 85
+255 255 85  170 85 0  0 0 0  85 85 85  85 85 85  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
+170 170 170  0 0 0  0 0 0  170 170 170  255 255 85  255 255 85
+170 170 170  0 0 0  170 170 170  85 85 85  0 0 0  255 255 255
+170 170 170  0 0 0  0 0 0  255 255 255  0 0 0  0 0 0
+170 170 170  170 170 170  0 0 0  0 0 0  85 85 85  0 0 0
+85 85 85  255 255 255  255 255 255  255 255 255  255 255 255  170 170 170
+255 255 255  255 255 255  255 255 255  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  170 170 170  255 255 255  170 170 170  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  255 255 255  255 255 85
+255 255 85  255 255 85  255 255 255  170 170 170  170 170 170  255 255 255
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  255 255 255  255 255 255
+85 85 85  0 0 0  0 0 0  255 255 255  255 255 85  255 255 85
+85 85 85  0 0 0  255 255 255  85 85 85  0 0 0  255 255 255
+85 85 85  0 0 0  85 85 85  255 255 255  85 85 85  85 85 85
+255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  85 85 85
+255 255 255  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
+170 170 170  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
+255 255 85  255 255 85  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  255 255 255
+0 0 0  0 0 0  85 85 85  255 255 85  255 255 85  255 255 255
+0 0 0  85 85 85  255 255 255  0 0 0  85 85 85  255 255 255
+85 85 85  0 0 0  170 170 170  255 255 255  170 170 170  170 170 170
+255 255 255  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+255 255 255  255 255 255  255 255 255  170 170 170  0 0 0  170 170 170
+255 255 255  255 255 255  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  255 255 255
+170 170 170  0 0 0  85 85 85  85 85 85  0 0 0  170 170 170
+255 255 85  255 255 85  255 255 255  170 170 170  170 170 170  170 170 170
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  170 170 170  0 0 0  0 0 0
+85 85 85  170 170 170  0 0 0  0 0 0  85 85 85  170 170 170
+0 0 0  0 0 0  170 170 170  255 255 85  255 255 85  170 170 170
+0 0 0  85 85 85  170 170 170  0 0 0  85 85 85  255 255 255
+0 0 0  0 0 0  170 170 170  170 170 170  170 170 170  255 255 255
+170 170 170  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+255 255 255  255 255 255  255 255 255  85 85 85  0 0 0  255 255 255
+255 255 255  255 255 255  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  255 255 255  255 255 255  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  170 170 170  255 255 255  255 255 85  255 255 255
+85 85 85  170 170 170  255 255 255  255 255 255  170 170 170  0 0 0
+170 170 170  255 255 85  255 255 85  255 255 255  170 170 170  255 255 255
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  170 170 170  0 0 0  0 0 0
+170 170 170  170 170 170  0 0 0  0 0 0  85 85 85  170 170 170
+0 0 0  0 0 0  170 170 170  255 255 85  255 255 255  85 85 85
+0 0 0  85 85 85  85 85 85  0 0 0  85 85 85  170 170 170
+0 0 0  0 0 0  255 255 255  85 85 85  0 0 0  170 170 170
+170 170 170  0 0 0  0 0 0  85 85 85  0 0 0  85 85 85
+255 255 255  255 255 255  255 255 255  85 85 85  85 85 85  255 255 255
+255 255 255  85 85 85  0 0 0  0 0 0  0 0 0  170 170 170
+170 170 170  170 170 170  255 255 255  0 0 0  0 0 0  0 0 0
+0 0 0  170 170 170  255 255 255  255 255 255  255 255 85  170 170 170
+255 255 255  255 255 255  255 255 85  255 255 85  170 170 170  0 0 0
+0 0 0  170 170 170  255 255 85  255 255 85  255 255 85  255 255 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  170 170 170  85 85 85  0 0 0  0 0 0
+255 255 255  85 85 85  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  0 0 0  255 255 255  255 255 85  255 255 255  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  85 85 85  255 255 255  0 0 0  0 0 0  255 255 255
+85 85 85  0 0 0  85 85 85  85 85 85  0 0 0  0 0 0
+255 255 255  255 255 255  255 255 255  85 85 85  170 170 170  255 255 255
+255 255 255  0 0 0  0 0 0  0 0 0  170 170 170  255 255 255
+170 170 170  85 85 85  170 170 170  0 0 0  0 0 0  85 85 85
+255 255 255  170 170 170  0 0 0  170 170 170  255 255 85  255 255 255
+255 255 255  170 170 170  255 255 255  255 255 255  85 85 85  0 0 0
+85 85 85  255 255 255  255 255 255  255 255 85  255 255 85  255 255 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
+85 85 85  0 0 0  0 0 0  0 0 0  255 255 255  0 0 0
+0 0 0  85 85 85  170 170 170  255 255 255  170 170 170  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  85 85 85  170 170 170  0 0 0  85 85 85  255 255 255
+0 0 0  0 0 0  170 170 170  170 170 170  0 0 0  0 0 0
+255 255 255  255 255 255  255 255 255  0 0 0  255 255 255  255 255 255
+170 170 170  0 0 0  0 0 0  170 170 170  255 255 255  85 85 85
+170 170 170  170 170 170  170 170 170  0 0 0  85 85 85  255 255 255
+170 170 170  0 0 0  85 85 85  255 255 255  255 255 85  170 170 170
+0 0 0  170 170 170  255 255 255  255 255 255  0 0 0  85 85 85
+255 255 255  170 170 170  0 0 0  170 170 170  255 255 85  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  170 170 170  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
+170 170 170  255 255 255  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  170 170 170
+0 0 0  0 0 0  255 255 255  170 170 170  0 0 0  0 0 0
+255 255 255  255 255 255  170 170 170  85 85 85  255 255 255  255 255 255
+85 85 85  0 0 0  170 170 170  170 170 170  0 0 0  0 0 0
+170 170 170  170 170 170  255 255 255  255 255 255  255 255 255  85 85 85
+0 0 0  0 0 0  255 255 255  255 255 255  170 170 170  0 0 0
+0 0 0  170 170 170  255 255 255  170 170 170  170 170 170  255 255 255
+85 85 85  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  170 170 170  255 255 255  170 170 170  0 0 0
+0 0 0  0 0 0  0 0 0  255 255 255  0 0 0  0 0 0
+255 255 255  255 255 255  0 0 0  0 0 0  255 255 255  170 170 170
+0 0 0  0 0 0  0 0 0  170 170 170  255 255 255  170 170 170
+0 0 0  0 0 0  255 255 255  170 170 170  0 0 0  0 0 0
+170 170 170  255 255 255  170 170 170  170 170 170  170 170 170  170 170 170
+0 0 0  85 85 85  85 85 85  0 0 0  0 0 0  0 0 0
+85 85 85  255 255 255  255 255 255  170 170 170  0 0 0  0 0 0
+0 0 0  170 170 170  255 255 255  170 170 170  0 0 0  0 0 0
+85 85 85  255 255 255  255 255 85  255 255 255  255 255 255  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
+85 85 85  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  255 255 85  255 255 85  255 255 85  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+255 255 85  170 170 170  170 170 170  170 170 170  255 255 85  255 255 85
+170 170 170  170 170 170  170 170 170  255 255 85  255 255 85  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  85 85 85  170 170 170  170 170 170  170 170 170
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  255 255 255  170 170 170  0 0 0  0 0 0  0 0 0
+0 0 0  255 255 255  255 255 255  255 255 255  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+170 170 170  85 85 85  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  85 85 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 85 85  85 85 85  0 0 0  0 0 0  0 0 0
+85 85 85  170 170 170  85 85 85  170 170 170  170 170 170  85 85 85
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  170 170 170  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  170 170 170  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+85 85 85  170 170 170  85 85 85  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  85 85 85  85 85 85  170 85 0  170 85 0
+170 85 0  255 85 85  255 85 85  255 85 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 85 85  170 85 0  85 85 85  0 0 0  0 0 0  85 85 85
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  170 170 170  170 170 170  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  85 85 85
+85 85 85  85 85 85  170 85 0  170 85 0  170 85 0  170 85 0
+255 85 85  255 85 85  255 255 85  255 255 85  255 255 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 255 85  255 85 85
+170 85 0  170 85 0  0 0 0  85 85 85  85 85 85  170 170 170
+170 170 170  0 0 0  170 170 170  255 255 255  170 170 170  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  170 170 170  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
+170 85 0  170 85 0  170 85 0  255 85 85  255 85 85  255 255 85
+255 255 85  255 255 85  255 255 85  255 255 85  255 85 85  170 85 0
+170 85 0  85 85 85  85 85 85  85 85 85  170 170 170  170 170 170
+0 0 0  0 0 0  255 255 255  255 255 255  85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  170 170 170  85 85 85  0 0 0
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  85 85 85  170 85 0  170 85 0  170 85 0
+170 85 0  255 85 85  255 85 85  255 85 85  170 85 0  170 85 0
+85 85 85  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
+0 0 0  85 85 85  255 255 255  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  170 170 170  85 85 85
+0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  85 85 85
+170 85 0  170 85 0  170 85 0  170 85 0  170 85 0  85 85 85
+0 0 0  0 0 0  0 0 0  85 85 85  170 170 170  0 0 0
+0 0 0  85 85 85  255 255 255  170 170 170  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  85 85 85  170 170 170
+85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  85 85 85  85 85 85  85 85 85  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  85 85 85  85 85 85  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  170 170 170
+170 170 170  170 170 170  170 170 170  170 170 170  170 170 170  85 85 85
+85 85 85  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0
+0 0 0  0 0 0
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index c95874f..9e90345 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -15,10 +15,9 @@
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -275,7 +274,7 @@
 	par->physbase = op->resource[2].start;
 	par->which_io = op->resource[2].flags & IORESOURCE_BITS;
 
-	sbusfb_fill_var(&info->var, dp->node, 8);
+	sbusfb_fill_var(&info->var, dp, 8);
 	info->var.red.length = 8;
 	info->var.green.length = 8;
 	info->var.blue.length = 8;
@@ -295,7 +294,7 @@
 	if (!info->screen_base)
 		goto out_unmap_regs;
 
-	p9100_blank(0, info);
+	p9100_blank(FB_BLANK_UNBLANK, info);
 
 	if (fb_alloc_cmap(&info->cmap, 256, 0))
 		goto out_unmap_screen;
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index 685761a..4db6b48 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -100,7 +100,6 @@
 		fb_dealloc_cmap(&info->cmap);
 		framebuffer_release(info);
 		platform_set_drvdata(pdev, NULL);
-		kfree(info);
 	}
 
 	pnx4008_free_dum_channel(channel_owned, pdev->id);
@@ -168,23 +167,21 @@
 
 	ret = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (ret < 0)
-		goto err2;
+		goto err1;
 
 	ret = register_framebuffer(info);
 	if (ret < 0)
-		goto err3;
+		goto err2;
 	platform_set_drvdata(pdev, info);
 
 	return 0;
 
-err3:
-	fb_dealloc_cmap(&info->cmap);
 err2:
-	framebuffer_release(info);
+	fb_dealloc_cmap(&info->cmap);
 err1:
 	pnx4008_free_dum_channel(channel_owned, pdev->id);
 err0:
-	kfree(info);
+	framebuffer_release(info);
 err:
 	return ret;
 }
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 3ab6e3d..48aea39 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1301,8 +1301,8 @@
 	}
 }
 
-static int pxafb_decode_mach_info(struct pxafb_info *fbi,
-				  struct pxafb_mach_info *inf)
+static void pxafb_decode_mach_info(struct pxafb_info *fbi,
+				   struct pxafb_mach_info *inf)
 {
 	unsigned int lcd_conn = inf->lcd_conn;
 
@@ -1333,7 +1333,7 @@
 		fbi->lccr0 = inf->lccr0;
 		fbi->lccr3 = inf->lccr3;
 		fbi->lccr4 = inf->lccr4;
-		return -EINVAL;
+		goto decode_mode;
 	}
 
 	if (lcd_conn == LCD_MONO_STN_8BPP)
@@ -1343,8 +1343,8 @@
 	fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
 	fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL)  ? LCCR3_PCP : 0;
 
+decode_mode:
 	pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes);
-	return 0;
 }
 
 static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 4deaac0..37d764a 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -10,18 +10,19 @@
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/of_device.h>
 
-#include <asm/oplib.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
 
-void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp)
+void sbusfb_fill_var(struct fb_var_screeninfo *var, struct device_node *dp,
+		     int bpp)
 {
 	memset(var, 0, sizeof(*var));
 
-	var->xres = prom_getintdefault(prom_node, "width", 1152);
-	var->yres = prom_getintdefault(prom_node, "height", 900);
+	var->xres = of_getintprop_default(dp, "width", 1152);
+	var->yres = of_getintprop_default(dp, "height", 900);
 	var->xres_virtual = var->xres;
 	var->yres_virtual = var->yres;
 	var->bits_per_pixel = bpp;
diff --git a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h
index 492828c..7ba3250 100644
--- a/drivers/video/sbuslib.h
+++ b/drivers/video/sbuslib.h
@@ -11,7 +11,8 @@
 #define SBUS_MMAP_FBSIZE(n) (-n)
 #define SBUS_MMAP_EMPTY	0x80000000
 
-extern void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp);
+extern void sbusfb_fill_var(struct fb_var_screeninfo *var,
+			    struct device_node *dp, int bpp);
 struct vm_area_struct;
 extern int sbusfb_mmap_helper(struct sbus_mmap_map *map,
 			      unsigned long physbase, unsigned long fbsize,
@@ -21,6 +22,6 @@
 			struct fb_info *info,
 			int type, int fb_depth, unsigned long fb_size);
 int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd,
-		unsigned long arg);
+			unsigned long arg);
 
 #endif /* _SBUSLIB_H */
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
index c3869a9..b1dde09 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/sunxvr2500.c
@@ -9,10 +9,9 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 
 struct s3d_info {
 	struct fb_info		*info;
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index 71bf3f1..c2ba51b 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -9,10 +9,9 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 
 /* XXX This device has a 'dev-comm' property which aparently is
  * XXX a pointer into the openfirmware's address space which is
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index a717743..2a03f78 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -17,10 +17,9 @@
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/mm.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -84,7 +83,7 @@
 
 struct tcx_thc {
 	u32 thc_rev;
-        u32 thc_pad0[511];
+	u32 thc_pad0[511];
 	u32 thc_hs;		/* hsync timing */
 	u32 thc_hsdvs;
 	u32 thc_hd;
@@ -126,10 +125,10 @@
 };
 
 /* Reset control plane so that WID is 8-bit plane. */
-static void __tcx_set_control_plane (struct tcx_par *par)
+static void __tcx_set_control_plane(struct tcx_par *par)
 {
 	u32 __iomem *p, *pend;
-        
+
 	if (par->lowdepth)
 		return;
 
@@ -143,8 +142,8 @@
 		sbus_writel(tmp, p);
 	}
 }
-                                                
-static void tcx_reset (struct fb_info *info)
+
+static void tcx_reset(struct fb_info *info)
 {
 	struct tcx_par *par = (struct tcx_par *) info->par;
 	unsigned long flags;
@@ -365,7 +364,8 @@
 			   info->screen_base, par->fbsize);
 }
 
-static int __devinit tcx_init_one(struct of_device *op)
+static int __devinit tcx_probe(struct of_device *op,
+			       const struct of_device_id *match)
 {
 	struct device_node *dp = op->node;
 	struct fb_info *info;
@@ -384,7 +384,7 @@
 	par->lowdepth =
 		(of_find_property(dp, "tcx-8-bit", NULL) != NULL);
 
-	sbusfb_fill_var(&info->var, dp->node, 8);
+	sbusfb_fill_var(&info->var, dp, 8);
 	info->var.red.length = 8;
 	info->var.green.length = 8;
 	info->var.blue.length = 8;
@@ -488,13 +488,6 @@
 	return err;
 }
 
-static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match)
-{
-	struct of_device *op = to_of_device(&dev->dev);
-
-	return tcx_init_one(op);
-}
-
 static int __devexit tcx_remove(struct of_device *op)
 {
 	struct fb_info *info = dev_get_drvdata(&op->dev);
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index bd54cd0..beefab2 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -27,7 +27,6 @@
 #define VERSION		"0.7.8-NEWAPI"
 
 struct tridentfb_par {
-	int vclk;		/* in MHz */
 	void __iomem *io_virt;	/* iospace virtual memory address */
 };
 
@@ -669,27 +668,26 @@
 		 (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
 }
 
-/* Use 20.12 fixed-point for NTSC value and frequency calculation */
-#define calc_freq(n, m, k)  ( ((unsigned long)0xE517 * (n + 8) / ((m + 2) * (1 << k))) >> 12 )
-
 /* Set dotclock frequency */
-static void set_vclk(int freq)
+static void set_vclk(unsigned long freq)
 {
 	int m, n, k;
-	int f, fi, d, di;
+	unsigned long f, fi, d, di;
 	unsigned char lo = 0, hi = 0;
 
-	d = 20;
+	d = 20000;
 	for (k = 2; k >= 0; k--)
 		for (m = 0; m < 63; m++)
 			for (n = 0; n < 128; n++) {
-				fi = calc_freq(n, m, k);
+				fi = ((14318l * (n + 8)) / (m + 2)) >> k;
 				if ((di = abs(fi - freq)) < d) {
 					d = di;
 					f = fi;
 					lo = n;
 					hi = (k << 6) | m;
 				}
+				if (fi > freq)
+					break;
 			}
 	if (chip3D) {
 		write3C4(ClockHigh, hi);
@@ -888,6 +886,8 @@
 	struct fb_var_screeninfo *var = &info->var;
 	int bpp = var->bits_per_pixel;
 	unsigned char tmp;
+	unsigned long vclk;
+
 	debug("enter\n");
 	hdispend = var->xres / 8 - 1;
 	hsyncstart = (var->xres + var->right_margin) / 8;
@@ -905,7 +905,6 @@
 	vblankstart = var->yres;
 	vblankend = vtotal + 2;
 
-	enable_mmio();
 	crtc_unlock();
 	write3CE(CyberControl, 8);
 
@@ -1015,11 +1014,11 @@
 	write3X4(Performance, 0x92);
 	write3X4(PCIReg, 0x07);		/* MMIO & PCI read and write burst enable */
 
-	/* convert from picoseconds to MHz */
-	par->vclk = 1000000 / info->var.pixclock;
+	/* convert from picoseconds to kHz */
+	vclk = PICOS2KHZ(info->var.pixclock);
 	if (bpp == 32)
-		par->vclk *= 2;
-	set_vclk(par->vclk);
+		vclk *= 2;
+	set_vclk(vclk);
 
 	write3C4(0, 3);
 	write3C4(1, 1);		/* set char clock 8 dots wide */
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
index 26e07df..c3bbd6a 100644
--- a/fs/9p/fid.h
+++ b/fs/9p/fid.h
@@ -22,6 +22,21 @@
 
 #include <linux/list.h>
 
+/**
+ * struct v9fs_dentry - 9p private data stored in dentry d_fsdata
+ * @lock: protects the fidlist
+ * @fidlist: list of FIDs currently associated with this dentry
+ *
+ * This structure defines the 9p private data associated with
+ * a particular dentry.  In particular, this private data is used
+ * to lookup which 9P FID handle should be used for a particular VFS
+ * operation.  FID handles are associated with dentries instead of
+ * inodes in order to more closely map functionality to the Plan 9
+ * expected behavior for FID reclaimation and tracking.
+ *
+ * See Also: Mapping FIDs to Linux VFS model in
+ * Design and Implementation of the Linux 9P File System documentation
+ */
 struct v9fs_dentry {
 	spinlock_t lock; /* protect fidlist */
 	struct list_head fidlist;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 9b0f022..047c791 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -71,19 +71,19 @@
 
 /**
  * v9fs_parse_options - parse mount options into session structure
- * @options: options string passed from mount
  * @v9ses: existing v9fs session information
  *
+ * Return 0 upon success, -ERRNO upon failure.
  */
 
-static void v9fs_parse_options(struct v9fs_session_info *v9ses)
+static int v9fs_parse_options(struct v9fs_session_info *v9ses)
 {
 	char *options;
 	substring_t args[MAX_OPT_ARGS];
 	char *p;
 	int option = 0;
 	char *s, *e;
-	int ret;
+	int ret = 0;
 
 	/* setup defaults */
 	v9ses->afid = ~0;
@@ -91,19 +91,26 @@
 	v9ses->cache = 0;
 
 	if (!v9ses->options)
-		return;
+		return 0;
 
 	options = kstrdup(v9ses->options, GFP_KERNEL);
+	if (!options) {
+		P9_DPRINTK(P9_DEBUG_ERROR,
+			   "failed to allocate copy of option string\n");
+		return -ENOMEM;
+	}
+
 	while ((p = strsep(&options, ",")) != NULL) {
 		int token;
 		if (!*p)
 			continue;
 		token = match_token(p, tokens, args);
 		if (token < Opt_uname) {
-			ret = match_int(&args[0], &option);
-			if (ret < 0) {
+			int r = match_int(&args[0], &option);
+			if (r < 0) {
 				P9_DPRINTK(P9_DEBUG_ERROR,
 					"integer field, but no integer?\n");
+				ret = r;
 				continue;
 			}
 		}
@@ -125,10 +132,10 @@
 			v9ses->afid = option;
 			break;
 		case Opt_uname:
-			match_strcpy(v9ses->uname, &args[0]);
+			match_strlcpy(v9ses->uname, &args[0], PATH_MAX);
 			break;
 		case Opt_remotename:
-			match_strcpy(v9ses->aname, &args[0]);
+			match_strlcpy(v9ses->aname, &args[0], PATH_MAX);
 			break;
 		case Opt_nodevmap:
 			v9ses->nodev = 1;
@@ -139,6 +146,13 @@
 
 		case Opt_access:
 			s = match_strdup(&args[0]);
+			if (!s) {
+				P9_DPRINTK(P9_DEBUG_ERROR,
+					   "failed to allocate copy"
+					   " of option argument\n");
+				ret = -ENOMEM;
+				break;
+			}
 			v9ses->flags &= ~V9FS_ACCESS_MASK;
 			if (strcmp(s, "user") == 0)
 				v9ses->flags |= V9FS_ACCESS_USER;
@@ -158,6 +172,7 @@
 		}
 	}
 	kfree(options);
+	return ret;
 }
 
 /**
@@ -173,6 +188,7 @@
 {
 	int retval = -EINVAL;
 	struct p9_fid *fid;
+	int rc;
 
 	v9ses->uname = __getname();
 	if (!v9ses->uname)
@@ -190,8 +206,21 @@
 	v9ses->uid = ~0;
 	v9ses->dfltuid = V9FS_DEFUID;
 	v9ses->dfltgid = V9FS_DEFGID;
-	v9ses->options = kstrdup(data, GFP_KERNEL);
-	v9fs_parse_options(v9ses);
+	if (data) {
+		v9ses->options = kstrdup(data, GFP_KERNEL);
+		if (!v9ses->options) {
+			P9_DPRINTK(P9_DEBUG_ERROR,
+			   "failed to allocate copy of option string\n");
+			retval = -ENOMEM;
+			goto error;
+		}
+	}
+
+	rc = v9fs_parse_options(v9ses);
+	if (rc < 0) {
+		retval = rc;
+		goto error;
+	}
 
 	v9ses->clnt = p9_client_create(dev_name, v9ses->options);
 
@@ -233,7 +262,6 @@
 	return fid;
 
 error:
-	v9fs_session_close(v9ses);
 	return ERR_PTR(retval);
 }
 
@@ -256,9 +284,12 @@
 }
 
 /**
- * v9fs_session_cancel - mark transport as disconnected
- * 	and cancel all pending requests.
+ * v9fs_session_cancel - terminate a session
+ * @v9ses: session to terminate
+ *
+ * mark transport as disconnected and cancel all pending requests.
  */
+
 void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
 	P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
 	p9_client_disconnect(v9ses->clnt);
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 7d3a101..a7d5671 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -21,18 +21,69 @@
  *
  */
 
-/*
-  * Session structure provides information for an opened session
-  *
-  */
+/**
+ * enum p9_session_flags - option flags for each 9P session
+ * @V9FS_EXTENDED: whether or not to use 9P2000.u extensions
+ * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
+ * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
+ * @V9FS_ACCESS_ANY: use a single attach for all users
+ * @V9FS_ACCESS_MASK: bit mask of different ACCESS options
+ *
+ * Session flags reflect options selected by users at mount time
+ */
+enum p9_session_flags {
+	V9FS_EXTENDED		= 0x01,
+	V9FS_ACCESS_SINGLE	= 0x02,
+	V9FS_ACCESS_USER	= 0x04,
+	V9FS_ACCESS_ANY		= 0x06,
+	V9FS_ACCESS_MASK	= 0x06,
+};
+
+/* possible values of ->cache */
+/**
+ * enum p9_cache_modes - user specified cache preferences
+ * @CACHE_NONE: do not cache data, dentries, or directory contents (default)
+ * @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
+ *
+ * eventually support loose, tight, time, session, default always none
+ */
+
+enum p9_cache_modes {
+	CACHE_NONE,
+	CACHE_LOOSE,
+};
+
+/**
+ * struct v9fs_session_info - per-instance session information
+ * @flags: session options of type &p9_session_flags
+ * @nodev: set to 1 to disable device mapping
+ * @debug: debug level
+ * @afid: authentication handle
+ * @cache: cache mode of type &p9_cache_modes
+ * @options: copy of options string given by user
+ * @uname: string user name to mount hierarchy as
+ * @aname: mount specifier for remote hierarchy
+ * @maxdata: maximum data to be sent/recvd per protocol message
+ * @dfltuid: default numeric userid to mount hierarchy as
+ * @dfltgid: default numeric groupid to mount hierarchy as
+ * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy
+ * @clnt: reference to 9P network client instantiated for this session
+ * @debugfs_dir: reference to debugfs_dir which can be used for add'l debug
+ *
+ * This structure holds state for each session instance established during
+ * a sys_mount() .
+ *
+ * Bugs: there seems to be a lot of state which could be condensed and/or
+ * removed.
+ */
 
 struct v9fs_session_info {
 	/* options */
-	unsigned char flags;	/* session flags */
-	unsigned char nodev;	/* set to 1 if no disable device mapping */
-	unsigned short debug;	/* debug level */
-	unsigned int afid;	/* authentication fid */
-	unsigned int cache;	/* cache mode */
+	unsigned char flags;
+	unsigned char nodev;
+	unsigned short debug;
+	unsigned int afid;
+	unsigned int cache;
 
 	char *options;		/* copy of mount options */
 	char *uname;		/* user name to mount as */
@@ -45,22 +96,6 @@
 	struct dentry *debugfs_dir;
 };
 
-/* session flags */
-enum {
-	V9FS_EXTENDED		= 0x01,	/* 9P2000.u */
-	V9FS_ACCESS_MASK	= 0x06,	/* access mask */
-	V9FS_ACCESS_SINGLE	= 0x02,	/* only one user can access the files */
-	V9FS_ACCESS_USER	= 0x04,	/* attache per user */
-	V9FS_ACCESS_ANY		= 0x06,	/* use the same attach for all users */
-};
-
-/* possible values of ->cache */
-/* eventually support loose, tight, time, session, default always none */
-enum {
-	CACHE_NONE,		/* default */
-	CACHE_LOOSE,		/* no consistency */
-};
-
 extern struct dentry *v9fs_debugfs_root;
 
 struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index 6248f0e..97d3aed 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -43,7 +43,7 @@
 /**
  * v9fs_vfs_readpage - read an entire page in from 9P
  *
- * @file: file being read
+ * @filp: file being read
  * @page: structure to page
  *
  */
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 0924d44..88e3787 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -60,7 +60,7 @@
 
 /**
  * v9fs_dir_readdir - read a directory
- * @filep: opened file structure
+ * @filp: opened file structure
  * @dirent: directory structure ???
  * @filldir: function to populate directory structure ???
  *
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index a616fff..0d55aff 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -90,10 +90,11 @@
 
 /**
  * v9fs_file_lock - lock a file (or directory)
- * @inode: inode to be opened
- * @file: file being opened
+ * @filp: file to be locked
+ * @cmd: lock command
+ * @fl: file lock structure
  *
- * XXX - this looks like a local only lock, we should extend into 9P
+ * Bugs: this looks like a local only lock, we should extend into 9P
  *       by using open exclusive
  */
 
@@ -118,7 +119,7 @@
 
 /**
  * v9fs_file_read - read from a file
- * @filep: file pointer to read
+ * @filp: file pointer to read
  * @data: data buffer to read data into
  * @count: size of buffer
  * @offset: offset at which to read data
@@ -142,7 +143,7 @@
 
 /**
  * v9fs_file_write - write to a file
- * @filep: file pointer to write
+ * @filp: file pointer to write
  * @data: data buffer to write data from
  * @count: size of buffer
  * @offset: offset at which to write data
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 6a28842..40fa807 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -129,6 +129,12 @@
 	return res;
 }
 
+/**
+ * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
+ * @uflags: flags to convert
+ *
+ */
+
 int v9fs_uflags2omode(int uflags)
 {
 	int ret;
@@ -312,6 +318,14 @@
 }
 */
 
+/**
+ * v9fs_inode_from_fid - populate an inode by issuing a attribute request
+ * @v9ses: session information
+ * @fid: fid to issue attribute request for
+ * @sb: superblock on which to create inode
+ *
+ */
+
 static struct inode *
 v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
 	struct super_block *sb)
@@ -384,9 +398,12 @@
 
 /**
  * v9fs_create - Create a file
+ * @v9ses: session information
+ * @dir: directory that dentry is being created in
  * @dentry:  dentry that is being created
  * @perm: create permissions
  * @mode: open mode
+ * @extension: 9p2000.u extension string to support devices, etc.
  *
  */
 static struct p9_fid *
@@ -461,7 +478,7 @@
 
 /**
  * v9fs_vfs_create - VFS hook to create files
- * @inode: directory inode that is being created
+ * @dir: directory inode that is being created
  * @dentry:  dentry that is being deleted
  * @mode: create permissions
  * @nd: path information
@@ -519,7 +536,7 @@
 
 /**
  * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
- * @inode:  inode that is being unlinked
+ * @dir:  inode that is being unlinked
  * @dentry: dentry that is being unlinked
  * @mode: mode for new directory
  *
@@ -703,9 +720,9 @@
 
 /**
  * v9fs_vfs_getattr - retrieve file metadata
- * @mnt - mount information
- * @dentry - file to get attributes on
- * @stat - metadata structure to populate
+ * @mnt: mount information
+ * @dentry: file to get attributes on
+ * @stat: metadata structure to populate
  *
  */
 
@@ -928,7 +945,7 @@
 /**
  * v9fs_vfs_readlink - read a symlink's location
  * @dentry: dentry for symlink
- * @buf: buffer to load symlink location into
+ * @buffer: buffer to load symlink location into
  * @buflen: length of buffer
  *
  */
@@ -996,10 +1013,12 @@
  * v9fs_vfs_put_link - release a symlink path
  * @dentry: dentry for symlink
  * @nd: nameidata
+ * @p: unused
  *
  */
 
-static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
+static void
+v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
 {
 	char *s = nd_get_link(nd);
 
@@ -1008,6 +1027,15 @@
 		__putname(s);
 }
 
+/**
+ * v9fs_vfs_mkspecial - create a special file
+ * @dir: inode to create special file in
+ * @dentry: dentry to create
+ * @mode: mode to create special file
+ * @extension: 9p2000.u format extension string representing special file
+ *
+ */
+
 static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
 	int mode, const char *extension)
 {
@@ -1037,7 +1065,7 @@
  * @dentry: dentry for symlink
  * @symname: symlink data
  *
- * See 9P2000.u RFC for more information
+ * See Also: 9P2000.u RFC for more information
  *
  */
 
@@ -1058,10 +1086,6 @@
  *
  */
 
-/* XXX - lots of code dup'd from symlink and creates,
- * figure out a better reuse strategy
- */
-
 static int
 v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
 	      struct dentry *dentry)
@@ -1098,7 +1122,7 @@
  * @dir: inode destination for new link
  * @dentry: dentry for file
  * @mode: mode for creation
- * @dev_t: device associated with special file
+ * @rdev: device associated with special file
  *
  */
 
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index a452ac6..bf59c39 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -75,6 +75,7 @@
  * v9fs_fill_super - populate superblock with info
  * @sb: superblock
  * @v9ses: session information
+ * @flags: flags propagated from v9fs_get_sb()
  *
  */
 
@@ -127,29 +128,26 @@
 	fid = v9fs_session_init(v9ses, dev_name, data);
 	if (IS_ERR(fid)) {
 		retval = PTR_ERR(fid);
-		fid = NULL;
-		kfree(v9ses);
-		v9ses = NULL;
-		goto error;
+		goto close_session;
 	}
 
 	st = p9_client_stat(fid);
 	if (IS_ERR(st)) {
 		retval = PTR_ERR(st);
-		goto error;
+		goto clunk_fid;
 	}
 
 	sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
 	if (IS_ERR(sb)) {
 		retval = PTR_ERR(sb);
-		goto error;
+		goto free_stat;
 	}
 	v9fs_fill_super(sb, v9ses, flags);
 
 	inode = v9fs_get_inode(sb, S_IFDIR | mode);
 	if (IS_ERR(inode)) {
 		retval = PTR_ERR(inode);
-		goto error;
+		goto release_sb;
 	}
 
 	inode->i_uid = uid;
@@ -158,7 +156,7 @@
 	root = d_alloc_root(inode);
 	if (!root) {
 		retval = -ENOMEM;
-		goto error;
+		goto release_sb;
 	}
 
 	sb->s_root = root;
@@ -169,21 +167,22 @@
 
 	return simple_set_mnt(mnt, sb);
 
-error:
-	kfree(st);
-	if (fid)
-		p9_client_clunk(fid);
-
-	if (v9ses) {
-		v9fs_session_close(v9ses);
-		kfree(v9ses);
-	}
-
+release_sb:
 	if (sb) {
 		up_write(&sb->s_umount);
 		deactivate_super(sb);
 	}
 
+free_stat:
+	kfree(st);
+
+clunk_fid:
+	p9_client_clunk(fid);
+
+close_session:
+	v9fs_session_close(v9ses);
+	kfree(v9ses);
+
 	return retval;
 }
 
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index d5bd497..223b191 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -48,7 +48,7 @@
  * affs fs inode data in memory
  */
 struct affs_inode_info {
-	u32	 i_opencnt;
+	atomic_t i_opencnt;
 	struct semaphore i_link_lock;		/* Protects internal inode access. */
 	struct semaphore i_ext_lock;		/* Protects internal inode access. */
 #define i_hash_lock i_ext_lock
@@ -170,8 +170,6 @@
 extern unsigned long		 affs_parent_ino(struct inode *dir);
 extern struct inode		*affs_new_inode(struct inode *dir);
 extern int			 affs_notify_change(struct dentry *dentry, struct iattr *attr);
-extern void			 affs_put_inode(struct inode *inode);
-extern void			 affs_drop_inode(struct inode *inode);
 extern void			 affs_delete_inode(struct inode *inode);
 extern void			 affs_clear_inode(struct inode *inode);
 extern struct inode		*affs_iget(struct super_block *sb,
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 1a4f092..6eac7bd 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -48,8 +48,9 @@
 {
 	if (atomic_read(&filp->f_count) != 1)
 		return 0;
-	pr_debug("AFFS: open(%d)\n", AFFS_I(inode)->i_opencnt);
-	AFFS_I(inode)->i_opencnt++;
+	pr_debug("AFFS: open(%lu,%d)\n",
+		 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
+	atomic_inc(&AFFS_I(inode)->i_opencnt);
 	return 0;
 }
 
@@ -58,10 +59,16 @@
 {
 	if (atomic_read(&filp->f_count) != 0)
 		return 0;
-	pr_debug("AFFS: release(%d)\n", AFFS_I(inode)->i_opencnt);
-	AFFS_I(inode)->i_opencnt--;
-	if (!AFFS_I(inode)->i_opencnt)
+	pr_debug("AFFS: release(%lu, %d)\n",
+		 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
+
+	if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) {
+		mutex_lock(&inode->i_mutex);
+		if (inode->i_size != AFFS_I(inode)->mmu_private)
+			affs_truncate(inode);
 		affs_free_prealloc(inode);
+		mutex_unlock(&inode->i_mutex);
+	}
 
 	return 0;
 }
@@ -180,7 +187,7 @@
 	/* inline the simplest case: same extended block as last time */
 	struct buffer_head *bh = AFFS_I(inode)->i_ext_bh;
 	if (ext == AFFS_I(inode)->i_ext_last)
-		atomic_inc(&bh->b_count);
+		get_bh(bh);
 	else
 		/* we have to do more (not inlined) */
 		bh = affs_get_extblock_slow(inode, ext);
@@ -306,7 +313,7 @@
 	affs_brelse(AFFS_I(inode)->i_ext_bh);
 	AFFS_I(inode)->i_ext_last = ext;
 	AFFS_I(inode)->i_ext_bh = bh;
-	atomic_inc(&bh->b_count);
+	get_bh(bh);
 
 	return bh;
 
@@ -324,7 +331,6 @@
 
 	pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block);
 
-
 	BUG_ON(block > (sector_t)0x7fffffffUL);
 
 	if (block >= AFFS_I(inode)->i_blkcnt) {
@@ -827,6 +833,8 @@
 		res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
 		if (!res)
 			res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
+		else
+			inode->i_size = AFFS_I(inode)->mmu_private;
 		mark_inode_dirty(inode);
 		return;
 	} else if (inode->i_size == AFFS_I(inode)->mmu_private)
@@ -862,6 +870,7 @@
 		blk++;
 	} else
 		AFFS_HEAD(ext_bh)->first_data = 0;
+	AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i);
 	size = AFFS_SB(sb)->s_hashsize;
 	if (size > blkcnt - blk + i)
 		size = blkcnt - blk + i;
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 27fe6cb..a13b334 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -58,7 +58,7 @@
 	AFFS_I(inode)->i_extcnt = 1;
 	AFFS_I(inode)->i_ext_last = ~1;
 	AFFS_I(inode)->i_protect = prot;
-	AFFS_I(inode)->i_opencnt = 0;
+	atomic_set(&AFFS_I(inode)->i_opencnt, 0);
 	AFFS_I(inode)->i_blkcnt = 0;
 	AFFS_I(inode)->i_lc = NULL;
 	AFFS_I(inode)->i_lc_size = 0;
@@ -108,8 +108,6 @@
 			inode->i_mode |= S_IFDIR;
 		} else
 			inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
-		if (tail->link_chain)
-			inode->i_nlink = 2;
 		/* Maybe it should be controlled by mount parameter? */
 		//inode->i_mode |= S_ISVTX;
 		inode->i_op = &affs_dir_inode_operations;
@@ -245,31 +243,12 @@
 }
 
 void
-affs_put_inode(struct inode *inode)
-{
-	pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
-	affs_free_prealloc(inode);
-}
-
-void
-affs_drop_inode(struct inode *inode)
-{
-	mutex_lock(&inode->i_mutex);
-	if (inode->i_size != AFFS_I(inode)->mmu_private)
-		affs_truncate(inode);
-	mutex_unlock(&inode->i_mutex);
-
-	generic_drop_inode(inode);
-}
-
-void
 affs_delete_inode(struct inode *inode)
 {
 	pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
 	truncate_inode_pages(&inode->i_data, 0);
 	inode->i_size = 0;
-	if (S_ISREG(inode->i_mode))
-		affs_truncate(inode);
+	affs_truncate(inode);
 	clear_inode(inode);
 	affs_free_block(inode->i_sb, inode->i_ino);
 }
@@ -277,9 +256,12 @@
 void
 affs_clear_inode(struct inode *inode)
 {
-	unsigned long cache_page = (unsigned long) AFFS_I(inode)->i_lc;
+	unsigned long cache_page;
 
 	pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
+
+	affs_free_prealloc(inode);
+	cache_page = (unsigned long)AFFS_I(inode)->i_lc;
 	if (cache_page) {
 		pr_debug("AFFS: freeing ext cache\n");
 		AFFS_I(inode)->i_lc = NULL;
@@ -316,7 +298,7 @@
 	inode->i_ino     = block;
 	inode->i_nlink   = 1;
 	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
-	AFFS_I(inode)->i_opencnt = 0;
+	atomic_set(&AFFS_I(inode)->i_opencnt, 0);
 	AFFS_I(inode)->i_blkcnt = 0;
 	AFFS_I(inode)->i_lc = NULL;
 	AFFS_I(inode)->i_lc_size = 0;
@@ -369,12 +351,12 @@
 	switch (type) {
 	case ST_LINKFILE:
 	case ST_LINKDIR:
-		inode_bh = bh;
 		retval = -ENOSPC;
 		block = affs_alloc_block(dir, dir->i_ino);
 		if (!block)
 			goto err;
 		retval = -EIO;
+		inode_bh = bh;
 		bh = affs_getzeroblk(sb, block);
 		if (!bh)
 			goto err;
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 2218f1e..cfcf1b6 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -234,7 +234,8 @@
 int
 affs_unlink(struct inode *dir, struct dentry *dentry)
 {
-	pr_debug("AFFS: unlink(dir=%d, \"%.*s\")\n", (u32)dir->i_ino,
+	pr_debug("AFFS: unlink(dir=%d, %lu \"%.*s\")\n", (u32)dir->i_ino,
+		 dentry->d_inode->i_ino,
 		 (int)dentry->d_name.len, dentry->d_name.name);
 
 	return affs_remove_header(dentry);
@@ -302,7 +303,8 @@
 int
 affs_rmdir(struct inode *dir, struct dentry *dentry)
 {
-	pr_debug("AFFS: rmdir(dir=%u, \"%.*s\")\n", (u32)dir->i_ino,
+	pr_debug("AFFS: rmdir(dir=%u, %lu \"%.*s\")\n", (u32)dir->i_ino,
+		 dentry->d_inode->i_ino,
 		 (int)dentry->d_name.len, dentry->d_name.name);
 
 	return affs_remove_header(dentry);
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 01d25d532..d214837 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -71,12 +71,18 @@
 
 static struct inode *affs_alloc_inode(struct super_block *sb)
 {
-	struct affs_inode_info *ei;
-	ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL);
-	if (!ei)
+	struct affs_inode_info *i;
+
+	i = kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL);
+	if (!i)
 		return NULL;
-	ei->vfs_inode.i_version = 1;
-	return &ei->vfs_inode;
+
+	i->vfs_inode.i_version = 1;
+	i->i_lc = NULL;
+	i->i_ext_bh = NULL;
+	i->i_pa_cnt = 0;
+
+	return &i->vfs_inode;
 }
 
 static void affs_destroy_inode(struct inode *inode)
@@ -114,8 +120,6 @@
 	.alloc_inode	= affs_alloc_inode,
 	.destroy_inode	= affs_destroy_inode,
 	.write_inode	= affs_write_inode,
-	.put_inode	= affs_put_inode,
-	.drop_inode	= affs_drop_inode,
 	.delete_inode	= affs_delete_inode,
 	.clear_inode	= affs_clear_inode,
 	.put_super	= affs_put_super,
diff --git a/fs/bio.c b/fs/bio.c
index 799f86d..7856257 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -158,7 +158,7 @@
 
 		bio_init(bio);
 		if (likely(nr_iovecs)) {
-			unsigned long idx = 0; /* shut up gcc */
+			unsigned long uninitialized_var(idx);
 
 			bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
 			if (unlikely(!bvl)) {
@@ -963,6 +963,7 @@
  *	@data: pointer to buffer to copy
  *	@len: length in bytes
  *	@gfp_mask: allocation flags for bio and page allocation
+ *	@reading: data direction is READ
  *
  *	copy the kernel address into a bio suitable for io to a block
  *	device. Returns an error pointer in case of error.
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 05c9da6..8355e91 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,6 @@
+Version 1.53
+------------
+
 Version 1.52
 ------------
 Fix oops on second mount to server when null auth is used.
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index bcda2c6..cb52cbb 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -460,8 +460,8 @@
 	unsigned char *sequence_end;
 	unsigned long *oid = NULL;
 	unsigned int cls, con, tag, oidlen, rc;
-	int use_ntlmssp = FALSE;
-	int use_kerberos = FALSE;
+	bool use_ntlmssp = false;
+	bool use_kerberos = false;
 
 	*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
 
@@ -561,15 +561,15 @@
 					if (compare_oid(oid, oidlen,
 							MSKRB5_OID,
 							MSKRB5_OID_LEN))
-						use_kerberos = TRUE;
+						use_kerberos = true;
 					else if (compare_oid(oid, oidlen,
 							     KRB5_OID,
 							     KRB5_OID_LEN))
-						use_kerberos = TRUE;
+						use_kerberos = true;
 					else if (compare_oid(oid, oidlen,
 							     NTLMSSP_OID,
 							     NTLMSSP_OID_LEN))
-						use_ntlmssp = TRUE;
+						use_ntlmssp = true;
 
 					kfree(oid);
 				}
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 95024c0..f6fdecf 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -93,15 +93,11 @@
 	/* find sharename end */
 	pSep++;
 	pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC));
-	if (!pSep) {
-		cERROR(1, ("%s:2 cant find share name in node name: %s",
-			__func__, node_name));
-		kfree(UNC);
-		return NULL;
+	if (pSep) {
+		/* trim path up to sharename end
+		 * now we have share name in UNC */
+		*pSep = 0;
 	}
-	/* trim path up to sharename end
-	 *          * now we have share name in UNC */
-	*pSep = 0;
 
 	return UNC;
 }
@@ -188,7 +184,7 @@
 		tkn_e = strchr(tkn_e+1, '\\');
 		if (tkn_e) {
 			strcat(mountdata, ",prefixpath=");
-			strcat(mountdata, tkn_e);
+			strcat(mountdata, tkn_e+1);
 		}
 	}
 
@@ -244,7 +240,8 @@
 		return NULL;
 
 	if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) {
-		/* we should use full path name to correct working with DFS */
+		int i;
+		/* we should use full path name for correct working with DFS */
 		l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) +
 					strnlen(search_path, MAX_PATHCONF) + 1;
 		tmp_path = kmalloc(l_max_len, GFP_KERNEL);
@@ -253,8 +250,14 @@
 			return NULL;
 		}
 		strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len);
-		strcat(tmp_path, search_path);
 		tmp_path[l_max_len-1] = 0;
+		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
+			for (i = 0; i < l_max_len; i++) {
+				if (tmp_path[i] == '\\')
+					tmp_path[i] = '/';
+			}
+		strncat(tmp_path, search_path, l_max_len - strlen(tmp_path));
+
 		full_path = tmp_path;
 		kfree(search_path);
 	} else {
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index e99d4fa..34902cf 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -559,7 +559,7 @@
 				       const char *path, const __u16 *pfid)
 {
 	struct cifsFileInfo *open_file = NULL;
-	int unlock_file = FALSE;
+	bool unlock_file = false;
 	int xid;
 	int rc = -EIO;
 	__u16 fid;
@@ -586,10 +586,10 @@
 	cifs_sb = CIFS_SB(sb);
 
 	if (open_file) {
-		unlock_file = TRUE;
+		unlock_file = true;
 		fid = open_file->netfid;
 	} else if (pfid == NULL) {
-		int oplock = FALSE;
+		int oplock = 0;
 		/* open file */
 		rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
 				READ_CONTROL, 0, &fid, &oplock, NULL,
@@ -604,7 +604,7 @@
 
 	rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
 	cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
-	if (unlock_file == TRUE) /* find_readable_file increments ref count */
+	if (unlock_file == true) /* find_readable_file increments ref count */
 		atomic_dec(&open_file->wrtPending);
 	else if (pfid == NULL) /* if opened above we have to close the handle */
 		CIFSSMBClose(xid, cifs_sb->tcon, fid);
@@ -619,7 +619,7 @@
 				struct inode *inode, const char *path)
 {
 	struct cifsFileInfo *open_file;
-	int unlock_file = FALSE;
+	bool unlock_file = false;
 	int xid;
 	int rc = -EIO;
 	__u16 fid;
@@ -640,10 +640,10 @@
 
 	open_file = find_readable_file(CIFS_I(inode));
 	if (open_file) {
-		unlock_file = TRUE;
+		unlock_file = true;
 		fid = open_file->netfid;
 	} else {
-		int oplock = FALSE;
+		int oplock = 0;
 		/* open file */
 		rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
 				WRITE_DAC, 0, &fid, &oplock, NULL,
@@ -658,7 +658,7 @@
 
 	rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
 	cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
-	if (unlock_file == TRUE)
+	if (unlock_file)
 		atomic_dec(&open_file->wrtPending);
 	else
 		CIFSSMBClose(xid, cifs_sb->tcon, fid);
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 39c2cbd..427a7c6 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -222,50 +222,50 @@
 cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
 	struct super_block *sb = dentry->d_sb;
-	int xid;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+	struct cifsTconInfo *tcon = cifs_sb->tcon;
 	int rc = -EOPNOTSUPP;
-	struct cifs_sb_info *cifs_sb;
-	struct cifsTconInfo *pTcon;
+	int xid;
 
 	xid = GetXid();
 
-	cifs_sb = CIFS_SB(sb);
-	pTcon = cifs_sb->tcon;
-
 	buf->f_type = CIFS_MAGIC_NUMBER;
 
-	/* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
-	buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would
-				      presumably be total path, but note
-				      that some servers (includinng Samba 3)
-				      have a shorter maximum path */
+	/*
+	 * PATH_MAX may be too long - it would presumably be total path,
+	 * but note that some servers (includinng Samba 3) have a shorter
+	 * maximum path.
+	 *
+	 * Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO.
+	 */
+	buf->f_namelen = PATH_MAX;
 	buf->f_files = 0;	/* undefined */
 	buf->f_ffree = 0;	/* unlimited */
 
-/* BB we could add a second check for a QFS Unix capability bit */
-/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */
-    if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
-			le64_to_cpu(pTcon->fsUnixInfo.Capability)))
-	    rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
+	/*
+	 * We could add a second check for a QFS Unix capability bit
+	 */
+	if ((tcon->ses->capabilities & CAP_UNIX) &&
+	    (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
+		rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
 
-    /* Only need to call the old QFSInfo if failed
-    on newer one */
-    if (rc)
-	if (pTcon->ses->capabilities & CAP_NT_SMBS)
-		rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
+	/*
+	 * Only need to call the old QFSInfo if failed on newer one,
+	 * e.g. by OS/2.
+	 **/
+	if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
+		rc = CIFSSMBQFSInfo(xid, tcon, buf);
 
-	/* Some old Windows servers also do not support level 103, retry with
-	   older level one if old server failed the previous call or we
-	   bypassed it because we detected that this was an older LANMAN sess */
+	/*
+	 * Some old Windows servers also do not support level 103, retry with
+	 * older level one if old server failed the previous call or we
+	 * bypassed it because we detected that this was an older LANMAN sess
+	 */
 	if (rc)
-		rc = SMBOldQFSInfo(xid, pTcon, buf);
-	/* int f_type;
-	   __fsid_t f_fsid;
-	   int f_namelen;  */
-	/* BB get from info in tcon struct at mount time call to QFSAttrInfo */
+		rc = SMBOldQFSInfo(xid, tcon, buf);
+
 	FreeXid(xid);
-	return 0;		/* always return success? what if volume is no
-				   longer available? */
+	return 0;
 }
 
 static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
@@ -306,8 +306,8 @@
 	/* Until the file is open and we have gotten oplock
 	info back from the server, can not assume caching of
 	file data or metadata */
-	cifs_inode->clientCanCacheRead = FALSE;
-	cifs_inode->clientCanCacheAll = FALSE;
+	cifs_inode->clientCanCacheRead = false;
+	cifs_inode->clientCanCacheAll = false;
 	cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
 
 	/* Can not set i_flags here - they get immediately overwritten
@@ -940,7 +940,7 @@
 				    rc = CIFSSMBLock(0, pTcon, netfid,
 					    0 /* len */ , 0 /* offset */, 0,
 					    0, LOCKING_ANDX_OPLOCK_RELEASE,
-					    0 /* wait flag */);
+					    false /* wait flag */);
 					cFYI(1, ("Oplock release rc = %d", rc));
 				}
 			} else
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index e1dd9f3..cd1301a 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -24,14 +24,6 @@
 
 #define ROOT_I 2
 
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
 extern struct file_system_type cifs_fs_type;
 extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
@@ -110,5 +102,5 @@
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.52"
+#define CIFS_VERSION   "1.53"
 #endif				/* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 69a2e19..b7d9f69 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -57,14 +57,6 @@
 
 #include "cifspdu.h"
 
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
 #ifndef XATTR_DOS_ATTRIB
 #define XATTR_DOS_ATTRIB "user.DOSATTRIB"
 #endif
@@ -147,7 +139,7 @@
 	enum protocolEnum protocolType;
 	char versionMajor;
 	char versionMinor;
-	unsigned svlocal:1;	/* local server or remote */
+	bool svlocal:1;			/* local server or remote */
 	atomic_t socketUseCount; /* number of open cifs sessions on socket */
 	atomic_t inFlight;  /* number of requests on the wire to server */
 #ifdef CONFIG_CIFS_STATS2
@@ -286,10 +278,10 @@
 	FILE_SYSTEM_DEVICE_INFO fsDevInfo;
 	FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
 	FILE_SYSTEM_UNIX_INFO fsUnixInfo;
-	unsigned ipc:1;		/* set if connection to IPC$ eg for RPC/PIPES */
-	unsigned retry:1;
-	unsigned nocase:1;
-	unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
+	bool ipc:1;		/* set if connection to IPC$ eg for RPC/PIPES */
+	bool retry:1;
+	bool nocase:1;
+	bool unix_ext:1;  /* if false disable Linux extensions to CIFS protocol
 				for this mount even if server would support */
 	/* BB add field for back pointer to sb struct(s)? */
 };
@@ -317,10 +309,10 @@
 	char *srch_entries_start;
 	char *presume_name;
 	unsigned int resume_name_len;
-	unsigned endOfSearch:1;
-	unsigned emptyDir:1;
-	unsigned unicode:1;
-	unsigned smallBuf:1; /* so we know which buf_release function to call */
+	bool endOfSearch:1;
+	bool emptyDir:1;
+	bool unicode:1;
+	bool smallBuf:1; /* so we know which buf_release function to call */
 };
 
 struct cifsFileInfo {
@@ -335,9 +327,9 @@
 	struct inode *pInode; /* needed for oplock break */
 	struct mutex lock_mutex;
 	struct list_head llist; /* list of byte range locks we have. */
-	unsigned closePend:1;	/* file is marked to close */
-	unsigned invalidHandle:1;  /* file closed via session abend */
-	unsigned messageMode:1;    /* for pipes: message vs byte mode */
+	bool closePend:1;	/* file is marked to close */
+	bool invalidHandle:1;	/* file closed via session abend */
+	bool messageMode:1;	/* for pipes: message vs byte mode */
 	atomic_t wrtPending;   /* handle in use - defer close */
 	struct semaphore fh_sem; /* prevents reopen race after dead ses*/
 	char *search_resume_name; /* BB removeme BB */
@@ -356,9 +348,9 @@
 	__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
 	atomic_t inUse;	 /* num concurrent users (local openers cifs) of file*/
 	unsigned long time;	/* jiffies of last update/check of inode */
-	unsigned clientCanCacheRead:1; /* read oplock */
-	unsigned clientCanCacheAll:1;  /* read and writebehind oplock */
-	unsigned oplockPending:1;
+	bool clientCanCacheRead:1;	/* read oplock */
+	bool clientCanCacheAll:1;	/* read and writebehind oplock */
+	bool oplockPending:1;
 	struct inode vfs_inode;
 };
 
@@ -426,9 +418,9 @@
 	struct smb_hdr *resp_buf;	/* response buffer */
 	int midState;	/* wish this were enum but can not pass to wait_event */
 	__u8 command;	/* smb command code */
-	unsigned largeBuf:1;    /* if valid response, is pointer to large buf */
-	unsigned multiRsp:1;   /* multiple trans2 responses for one request  */
-	unsigned multiEnd:1; /* both received */
+	bool largeBuf:1;	/* if valid response, is pointer to large buf */
+	bool multiRsp:1;	/* multiple trans2 responses for one request  */
+	bool multiEnd:1;	/* both received */
 };
 
 struct oplock_q_entry {
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 9f49c2f..c43bf4b 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -340,6 +340,7 @@
 #define OPEN_NO_RECALL          0x00400000
 #define OPEN_FREE_SPACE_QUERY   0x00800000	/* should be zero */
 #define CREATE_OPTIONS_MASK     0x007FFFFF
+#define CREATE_OPTION_READONLY	0x10000000
 #define CREATE_OPTION_SPECIAL   0x20000000   /* system. NB not sent over wire */
 
 /* ImpersonationLevel flags */
@@ -2050,7 +2051,7 @@
 						      to 0xFFFF00 */
 #define CIFS_UNIX_LARGE_WRITE_CAP       0x00000080
 #define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */
-#define CIFS_UNIX_TRANPSORT_ENCRYPTION_MANDATORY_CAP  0x00000200 /* must do  */
+#define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP  0x00000200 /* must do  */
 #define CIFS_UNIX_PROXY_CAP             0x00000400 /* Proxy cap: 0xACE ioctl and
 						      QFS PROXY call */
 #ifdef CONFIG_CIFS_POSIX
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 50f9fda..d481f6c 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -59,8 +59,9 @@
 			struct smb_hdr *out_buf,
 			int *bytes_returned);
 extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
-extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
-extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
+extern bool is_valid_oplock_break(struct smb_hdr *smb,
+				  struct TCP_Server_Info *);
+extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *);
@@ -69,7 +70,7 @@
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
 			enum securityEnum *secType);
-extern int cifs_inet_pton(int, char *source, void *dst);
+extern int cifs_inet_pton(const int, const char *source, void *dst);
 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
 			    const struct cifsTconInfo *, int /* length of
@@ -187,12 +188,12 @@
 #endif /* possibly unneeded function */
 extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
 			const char *fileName, __u64 size,
-			int setAllocationSizeFlag,
+			bool setAllocationSizeFlag,
 			const struct nls_table *nls_codepage,
 			int remap_special_chars);
 extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
 			 __u64 size, __u16 fileHandle, __u32 opener_pid,
-			int AllocSizeFlag);
+			bool AllocSizeFlag);
 extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
 			char *full_path, __u64 mode, __u64 uid,
 			__u64 gid, dev_t dev,
@@ -291,11 +292,11 @@
 			const __u16 netfid, const __u64 len,
 			const __u64 offset, const __u32 numUnlock,
 			const __u32 numLock, const __u8 lockType,
-			const int waitFlag);
+			const bool waitFlag);
 extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
 			const __u16 smb_file_id, const int get_flag,
 			const __u64 len, struct file_lock *,
-			const __u16 lock_type, const int waitFlag);
+			const __u16 lock_type, const bool waitFlag);
 extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
 extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
 
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 4728fa9..95fbba4e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -95,7 +95,7 @@
 	list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
 		open_file = list_entry(tmp, struct cifsFileInfo, tlist);
 		if (open_file)
-			open_file->invalidHandle = TRUE;
+			open_file->invalidHandle = true;
 	}
 	write_unlock(&GlobalSMBSeslock);
 	/* BB Add call to invalidate_inodes(sb) for all superblocks mounted
@@ -141,7 +141,7 @@
 				if (tcon->ses->server->tcpStatus ==
 							CifsNeedReconnect) {
 					/* on "soft" mounts we wait once */
-					if ((tcon->retry == FALSE) ||
+					if (!tcon->retry ||
 					   (tcon->ses->status == CifsExiting)) {
 						cFYI(1, ("gave up waiting on "
 						      "reconnect in smb_init"));
@@ -289,7 +289,7 @@
 				if (tcon->ses->server->tcpStatus ==
 						CifsNeedReconnect) {
 					/* on "soft" mounts we wait once */
-					if ((tcon->retry == FALSE) ||
+					if (!tcon->retry ||
 					   (tcon->ses->status == CifsExiting)) {
 						cFYI(1, ("gave up waiting on "
 						      "reconnect in smb_init"));
@@ -1224,11 +1224,8 @@
 	else /* BB FIXME BB */
 		pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
 
-	/* if ((omode & S_IWUGO) == 0)
-		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
-	/*  Above line causes problems due to vfs splitting create into two
-	    pieces - need to set mode after file created not while it is
-	    being created */
+	if (create_options & CREATE_OPTION_READONLY)
+		pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
 
 	/* BB FIXME BB */
 /*	pSMB->CreateOptions = cpu_to_le32(create_options &
@@ -1331,17 +1328,16 @@
 		pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
 	else
 		pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
+
 	/* XP does not handle ATTR_POSIX_SEMANTICS */
 	/* but it helps speed up case sensitive checks for other
 	servers such as Samba */
 	if (tcon->ses->capabilities & CAP_UNIX)
 		pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
 
-	/* if ((omode & S_IWUGO) == 0)
-		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
-	/*  Above line causes problems due to vfs splitting create into two
-		pieces - need to set mode after file created not while it is
-		being created */
+	if (create_options & CREATE_OPTION_READONLY)
+		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
+
 	pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
 	pSMB->CreateDisposition = cpu_to_le32(openDisposition);
 	pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
@@ -1686,7 +1682,7 @@
 CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
 	    const __u16 smb_file_id, const __u64 len,
 	    const __u64 offset, const __u32 numUnlock,
-	    const __u32 numLock, const __u8 lockType, const int waitFlag)
+	    const __u32 numLock, const __u8 lockType, const bool waitFlag)
 {
 	int rc = 0;
 	LOCK_REQ *pSMB = NULL;
@@ -1695,7 +1691,7 @@
 	int timeout = 0;
 	__u16 count;
 
-	cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock));
+	cFYI(1, ("CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock));
 	rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
 
 	if (rc)
@@ -1706,7 +1702,7 @@
 	if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
 		timeout = CIFS_ASYNC_OP; /* no response expected */
 		pSMB->Timeout = 0;
-	} else if (waitFlag == TRUE) {
+	} else if (waitFlag) {
 		timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
 		pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
 	} else {
@@ -1756,7 +1752,7 @@
 CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
 		const __u16 smb_file_id, const int get_flag, const __u64 len,
 		struct file_lock *pLockData, const __u16 lock_type,
-		const int waitFlag)
+		const bool waitFlag)
 {
 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
 	struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -3581,9 +3577,9 @@
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 		if (rc == 0) {
 			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-				psrch_inf->unicode = TRUE;
+				psrch_inf->unicode = true;
 			else
-				psrch_inf->unicode = FALSE;
+				psrch_inf->unicode = false;
 
 			psrch_inf->ntwrk_buf_start = (char *)pSMBr;
 			psrch_inf->smallBuf = 0;
@@ -3594,9 +3590,9 @@
 			       le16_to_cpu(pSMBr->t2.ParameterOffset));
 
 			if (parms->EndofSearch)
-				psrch_inf->endOfSearch = TRUE;
+				psrch_inf->endOfSearch = true;
 			else
-				psrch_inf->endOfSearch = FALSE;
+				psrch_inf->endOfSearch = false;
 
 			psrch_inf->entries_in_buffer =
 					le16_to_cpu(parms->SearchCount);
@@ -3624,7 +3620,7 @@
 
 	cFYI(1, ("In FindNext"));
 
-	if (psrch_inf->endOfSearch == TRUE)
+	if (psrch_inf->endOfSearch)
 		return -ENOENT;
 
 	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3682,7 +3678,7 @@
 	cifs_stats_inc(&tcon->num_fnext);
 	if (rc) {
 		if (rc == -EBADF) {
-			psrch_inf->endOfSearch = TRUE;
+			psrch_inf->endOfSearch = true;
 			rc = 0; /* search probably was closed at end of search*/
 		} else
 			cFYI(1, ("FindNext returned = %d", rc));
@@ -3692,9 +3688,9 @@
 		if (rc == 0) {
 			/* BB fixme add lock for file (srch_info) struct here */
 			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-				psrch_inf->unicode = TRUE;
+				psrch_inf->unicode = true;
 			else
-				psrch_inf->unicode = FALSE;
+				psrch_inf->unicode = false;
 			response_data = (char *) &pSMBr->hdr.Protocol +
 			       le16_to_cpu(pSMBr->t2.ParameterOffset);
 			parms = (T2_FNEXT_RSP_PARMS *)response_data;
@@ -3709,9 +3705,9 @@
 			psrch_inf->ntwrk_buf_start = (char *)pSMB;
 			psrch_inf->smallBuf = 0;
 			if (parms->EndofSearch)
-				psrch_inf->endOfSearch = TRUE;
+				psrch_inf->endOfSearch = true;
 			else
-				psrch_inf->endOfSearch = FALSE;
+				psrch_inf->endOfSearch = false;
 			psrch_inf->entries_in_buffer =
 						le16_to_cpu(parms->SearchCount);
 			psrch_inf->index_of_last_entry +=
@@ -4586,7 +4582,7 @@
 
 int
 CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
-	      __u64 size, int SetAllocation,
+	      __u64 size, bool SetAllocation,
 	      const struct nls_table *nls_codepage, int remap)
 {
 	struct smb_com_transaction2_spi_req *pSMB = NULL;
@@ -4675,7 +4671,7 @@
 
 int
 CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
-		   __u16 fid, __u32 pid_of_opener, int SetAllocation)
+		   __u16 fid, __u32 pid_of_opener, bool SetAllocation)
 {
 	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
 	char *data_offset;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index e171067..f428bf3 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -49,8 +49,6 @@
 #define CIFS_PORT 445
 #define RFC1001_PORT 139
 
-static DECLARE_COMPLETION(cifsd_complete);
-
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
 			 unsigned char *p24);
 
@@ -71,23 +69,23 @@
 	mode_t file_mode;
 	mode_t dir_mode;
 	unsigned secFlg;
-	unsigned rw:1;
-	unsigned retry:1;
-	unsigned intr:1;
-	unsigned setuids:1;
-	unsigned override_uid:1;
-	unsigned override_gid:1;
-	unsigned noperm:1;
-	unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
-	unsigned cifs_acl:1;
-	unsigned no_xattr:1;   /* set if xattr (EA) support should be disabled*/
-	unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
-	unsigned direct_io:1;
-	unsigned remap:1;   /* set to remap seven reserved chars in filenames */
-	unsigned posix_paths:1;   /* unset to not ask for posix pathnames. */
-	unsigned no_linux_ext:1;
-	unsigned sfu_emul:1;
-	unsigned nullauth:1; /* attempt to authenticate with null user */
+	bool rw:1;
+	bool retry:1;
+	bool intr:1;
+	bool setuids:1;
+	bool override_uid:1;
+	bool override_gid:1;
+	bool noperm:1;
+	bool no_psx_acl:1; /* set if posix acl support should be disabled */
+	bool cifs_acl:1;
+	bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
+	bool server_ino:1; /* use inode numbers from server ie UniqueId */
+	bool direct_io:1;
+	bool remap:1;     /* set to remap seven reserved chars in filenames */
+	bool posix_paths:1;   /* unset to not ask for posix pathnames. */
+	bool no_linux_ext:1;
+	bool sfu_emul:1;
+	bool nullauth:1; /* attempt to authenticate with null user */
 	unsigned nocase;     /* request case insensitive filenames */
 	unsigned nobrl;      /* disable sending byte range locks to srv */
 	unsigned int rsize;
@@ -345,18 +343,16 @@
 	struct task_struct *task_to_wake = NULL;
 	struct mid_q_entry *mid_entry;
 	char temp;
-	int isLargeBuf = FALSE;
-	int isMultiRsp;
+	bool isLargeBuf = false;
+	bool isMultiRsp;
 	int reconnect;
 
 	current->flags |= PF_MEMALLOC;
-	server->tsk = current;	/* save process info to wake at shutdown */
 	cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
 	write_lock(&GlobalSMBSeslock);
 	atomic_inc(&tcpSesAllocCount);
 	length = tcpSesAllocCount.counter;
 	write_unlock(&GlobalSMBSeslock);
-	complete(&cifsd_complete);
 	if (length  > 1)
 		mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
 				GFP_KERNEL);
@@ -390,8 +386,8 @@
 		} else /* if existing small buf clear beginning */
 			memset(smallbuf, 0, sizeof(struct smb_hdr));
 
-		isLargeBuf = FALSE;
-		isMultiRsp = FALSE;
+		isLargeBuf = false;
+		isMultiRsp = false;
 		smb_buffer = smallbuf;
 		iov.iov_base = smb_buffer;
 		iov.iov_len = 4;
@@ -517,7 +513,7 @@
 		reconnect = 0;
 
 		if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
-			isLargeBuf = TRUE;
+			isLargeBuf = true;
 			memcpy(bigbuf, smallbuf, 4);
 			smb_buffer = bigbuf;
 		}
@@ -582,16 +578,18 @@
 			    (mid_entry->command == smb_buffer->Command)) {
 				if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
 					/* We have a multipart transact2 resp */
-					isMultiRsp = TRUE;
+					isMultiRsp = true;
 					if (mid_entry->resp_buf) {
 						/* merge response - fix up 1st*/
 						if (coalesce_t2(smb_buffer,
 							mid_entry->resp_buf)) {
-							mid_entry->multiRsp = 1;
+							mid_entry->multiRsp =
+								 true;
 							break;
 						} else {
 							/* all parts received */
-							mid_entry->multiEnd = 1;
+							mid_entry->multiEnd =
+								 true;
 							goto multi_t2_fnd;
 						}
 					} else {
@@ -603,17 +601,15 @@
 							/* Have first buffer */
 							mid_entry->resp_buf =
 								 smb_buffer;
-							mid_entry->largeBuf = 1;
+							mid_entry->largeBuf =
+								 true;
 							bigbuf = NULL;
 						}
 					}
 					break;
 				}
 				mid_entry->resp_buf = smb_buffer;
-				if (isLargeBuf)
-					mid_entry->largeBuf = 1;
-				else
-					mid_entry->largeBuf = 0;
+				mid_entry->largeBuf = isLargeBuf;
 multi_t2_fnd:
 				task_to_wake = mid_entry->tsk;
 				mid_entry->midState = MID_RESPONSE_RECEIVED;
@@ -638,8 +634,8 @@
 					smallbuf = NULL;
 			}
 			wake_up_process(task_to_wake);
-		} else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
-		    && (isMultiRsp == FALSE)) {
+		} else if (!is_valid_oplock_break(smb_buffer, server) &&
+			   !isMultiRsp) {
 			cERROR(1, ("No task to wake, unknown frame received! "
 				   "NumMids %d", midCount.counter));
 			cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
@@ -654,10 +650,20 @@
 
 	spin_lock(&GlobalMid_Lock);
 	server->tcpStatus = CifsExiting;
-	server->tsk = NULL;
+	spin_unlock(&GlobalMid_Lock);
+
+	/* don't exit until kthread_stop is called */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	while (!kthread_should_stop()) {
+		schedule();
+		set_current_state(TASK_UNINTERRUPTIBLE);
+	}
+	set_current_state(TASK_RUNNING);
+
 	/* check if we have blocked requests that need to free */
 	/* Note that cifs_max_pending is normally 50, but
 	can be set at module install time to as little as two */
+	spin_lock(&GlobalMid_Lock);
 	if (atomic_read(&server->inFlight) >= cifs_max_pending)
 		atomic_set(&server->inFlight, cifs_max_pending - 1);
 	/* We do not want to set the max_pending too low or we
@@ -825,7 +831,7 @@
 	vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
 
 	/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
-	vol->rw = TRUE;
+	vol->rw = true;
 	/* default is always to request posix paths. */
 	vol->posix_paths = 1;
 
@@ -1181,7 +1187,7 @@
 		} else if (strnicmp(data, "guest", 5) == 0) {
 			/* ignore */
 		} else if (strnicmp(data, "rw", 2) == 0) {
-			vol->rw = TRUE;
+			vol->rw = true;
 		} else if ((strnicmp(data, "suid", 4) == 0) ||
 				   (strnicmp(data, "nosuid", 6) == 0) ||
 				   (strnicmp(data, "exec", 4) == 0) ||
@@ -1197,7 +1203,7 @@
 			    is ok to just ignore them */
 			continue;
 		} else if (strnicmp(data, "ro", 2) == 0) {
-			vol->rw = FALSE;
+			vol->rw = false;
 		} else if (strnicmp(data, "hard", 4) == 0) {
 			vol->retry = 1;
 		} else if (strnicmp(data, "soft", 4) == 0) {
@@ -1305,6 +1311,9 @@
 						    "begin with // or \\\\ \n");
 				return 1;
 			}
+			value = strpbrk(vol->UNC+2, "/\\");
+			if (value)
+				*value = '\\';
 		} else {
 			printk(KERN_WARNING "CIFS: UNC name too long\n");
 			return 1;
@@ -1318,42 +1327,43 @@
 
 static struct cifsSesInfo *
 cifs_find_tcp_session(struct in_addr *target_ip_addr,
-		struct in6_addr *target_ip6_addr,
-		 char *userName, struct TCP_Server_Info **psrvTcp)
+		      struct in6_addr *target_ip6_addr,
+		      char *userName, struct TCP_Server_Info **psrvTcp)
 {
 	struct list_head *tmp;
 	struct cifsSesInfo *ses;
-	*psrvTcp = NULL;
-	read_lock(&GlobalSMBSeslock);
 
+	*psrvTcp = NULL;
+
+	read_lock(&GlobalSMBSeslock);
 	list_for_each(tmp, &GlobalSMBSessionList) {
 		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
-		if (ses->server) {
-			if ((target_ip_addr &&
-				(ses->server->addr.sockAddr.sin_addr.s_addr
-				  == target_ip_addr->s_addr)) || (target_ip6_addr
-				&& memcmp(&ses->server->addr.sockAddr6.sin6_addr,
-					target_ip6_addr, sizeof(*target_ip6_addr)))) {
-				/* BB lock server and tcp session and increment
-				      use count here?? */
+		if (!ses->server)
+			continue;
 
-				/* found a match on the TCP session */
-				*psrvTcp = ses->server;
+		if (target_ip_addr &&
+		    ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
+				continue;
+		else if (target_ip6_addr &&
+			 memcmp(&ses->server->addr.sockAddr6.sin6_addr,
+				target_ip6_addr, sizeof(*target_ip6_addr)))
+				continue;
+		/* BB lock server and tcp session; increment use count here?? */
 
-				/* BB check if reconnection needed */
-				if (strncmp
-				    (ses->userName, userName,
-				     MAX_USERNAME_SIZE) == 0){
-					read_unlock(&GlobalSMBSeslock);
-					/* Found exact match on both TCP and
-					   SMB sessions */
-					return ses;
-				}
-			}
+		/* found a match on the TCP session */
+		*psrvTcp = ses->server;
+
+		/* BB check if reconnection needed */
+		if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
+			read_unlock(&GlobalSMBSeslock);
+			/* Found exact match on both TCP and
+			   SMB sessions */
+			return ses;
 		}
 		/* else tcp and smb sessions need reconnection */
 	}
 	read_unlock(&GlobalSMBSeslock);
+
 	return NULL;
 }
 
@@ -1362,45 +1372,43 @@
 {
 	struct list_head *tmp;
 	struct cifsTconInfo *tcon;
+	__be32 old_ip;
 
 	read_lock(&GlobalSMBSeslock);
+
 	list_for_each(tmp, &GlobalTreeConnectionList) {
 		cFYI(1, ("Next tcon"));
 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-		if (tcon->ses) {
-			if (tcon->ses->server) {
-				cFYI(1,
-				     ("old ip addr: %x == new ip %x ?",
-				      tcon->ses->server->addr.sockAddr.sin_addr.
-				      s_addr, new_target_ip_addr));
-				if (tcon->ses->server->addr.sockAddr.sin_addr.
-				    s_addr == new_target_ip_addr) {
-	/* BB lock tcon, server and tcp session and increment use count here? */
-					/* found a match on the TCP session */
-					/* BB check if reconnection needed */
-					cFYI(1,
-					      ("IP match, old UNC: %s new: %s",
-					      tcon->treeName, uncName));
-					if (strncmp
-					    (tcon->treeName, uncName,
-					     MAX_TREE_SIZE) == 0) {
-						cFYI(1,
-						     ("and old usr: %s new: %s",
-						      tcon->treeName, uncName));
-						if (strncmp
-						    (tcon->ses->userName,
-						     userName,
-						     MAX_USERNAME_SIZE) == 0) {
-							read_unlock(&GlobalSMBSeslock);
-							/* matched smb session
-							(user name */
-							return tcon;
-						}
-					}
-				}
-			}
-		}
+		if (!tcon->ses || !tcon->ses->server)
+			continue;
+
+		old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr;
+		cFYI(1, ("old ip addr: %x == new ip %x ?",
+			old_ip, new_target_ip_addr));
+
+		if (old_ip != new_target_ip_addr)
+			continue;
+
+		/* BB lock tcon, server, tcp session and increment use count? */
+		/* found a match on the TCP session */
+		/* BB check if reconnection needed */
+		cFYI(1, ("IP match, old UNC: %s new: %s",
+			tcon->treeName, uncName));
+
+		if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE))
+			continue;
+
+		cFYI(1, ("and old usr: %s new: %s",
+			tcon->treeName, uncName));
+
+		if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE))
+			continue;
+
+		/* matched smb session (user name) */
+		read_unlock(&GlobalSMBSeslock);
+		return tcon;
 	}
+
 	read_unlock(&GlobalSMBSeslock);
 	return NULL;
 }
@@ -1982,7 +1990,6 @@
 				kfree(srvTcp->hostname);
 				goto out;
 			}
-			wait_for_completion(&cifsd_complete);
 			rc = 0;
 			memcpy(srvTcp->workstation_RFC1001_name,
 				volume_info.source_rfc1001_name, 16);
@@ -2189,15 +2196,12 @@
 			srvTcp->tcpStatus = CifsExiting;
 			spin_unlock(&GlobalMid_Lock);
 			if (srvTcp->tsk) {
-				struct task_struct *tsk;
 				/* If we could verify that kthread_stop would
 				   always wake up processes blocked in
 				   tcp in recv_mesg then we could remove the
 				   send_sig call */
 				force_sig(SIGKILL, srvTcp->tsk);
-				tsk = srvTcp->tsk;
-				if (tsk)
-					kthread_stop(tsk);
+				kthread_stop(srvTcp->tsk);
 			}
 		}
 		 /* If find_unc succeeded then rc == 0 so we can not end */
@@ -2213,23 +2217,17 @@
 					if ((temp_rc == -ESHUTDOWN) &&
 					    (pSesInfo->server) &&
 					    (pSesInfo->server->tsk)) {
-						struct task_struct *tsk;
 						force_sig(SIGKILL,
 							pSesInfo->server->tsk);
-						tsk = pSesInfo->server->tsk;
-						if (tsk)
-							kthread_stop(tsk);
+						kthread_stop(pSesInfo->server->tsk);
 					}
 				} else {
 					cFYI(1, ("No session or bad tcon"));
 					if ((pSesInfo->server) &&
 					    (pSesInfo->server->tsk)) {
-						struct task_struct *tsk;
 						force_sig(SIGKILL,
 							pSesInfo->server->tsk);
-						tsk = pSesInfo->server->tsk;
-						if (tsk)
-							kthread_stop(tsk);
+						kthread_stop(pSesInfo->server->tsk);
 					}
 				}
 				sesInfoFree(pSesInfo);
@@ -2602,7 +2600,7 @@
 
 static int
 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
-			      struct cifsSesInfo *ses, int *pNTLMv2_flag,
+			      struct cifsSesInfo *ses, bool *pNTLMv2_flag,
 			      const struct nls_table *nls_codepage)
 {
 	struct smb_hdr *smb_buffer;
@@ -2625,7 +2623,7 @@
 	if (ses == NULL)
 		return -EINVAL;
 	domain = ses->domainName;
-	*pNTLMv2_flag = FALSE;
+	*pNTLMv2_flag = false;
 	smb_buffer = cifs_buf_get();
 	if (smb_buffer == NULL) {
 		return -ENOMEM;
@@ -2778,7 +2776,7 @@
 				       CIFS_CRYPTO_KEY_SIZE);
 				if (SecurityBlob2->NegotiateFlags &
 					cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
-					*pNTLMv2_flag = TRUE;
+					*pNTLMv2_flag = true;
 
 				if ((SecurityBlob2->NegotiateFlags &
 					cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
@@ -2939,7 +2937,7 @@
 }
 static int
 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-			char *ntlm_session_key, int ntlmv2_flag,
+			char *ntlm_session_key, bool ntlmv2_flag,
 			const struct nls_table *nls_codepage)
 {
 	struct smb_hdr *smb_buffer;
@@ -3556,8 +3554,6 @@
 	cifs_sb->prepath = NULL;
 	kfree(tmp);
 	if (ses)
-		schedule_timeout_interruptible(msecs_to_jiffies(500));
-	if (ses)
 		sesInfoFree(ses);
 
 	FreeXid(xid);
@@ -3569,7 +3565,7 @@
 {
 	int rc = 0;
 	char ntlm_session_key[CIFS_SESS_KEY_SIZE];
-	int ntlmv2_flag = FALSE;
+	bool ntlmv2_flag = false;
 	int first_time = 0;
 
 	/* what if server changes its buffer size after dropping the session? */
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 0f5c62b..e4e0078 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -119,6 +119,7 @@
 {
 	int rc = -ENOENT;
 	int xid;
+	int create_options = CREATE_NOT_DIR;
 	int oplock = 0;
 	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
 	__u16 fileHandle;
@@ -130,7 +131,7 @@
 	struct cifsFileInfo *pCifsFile = NULL;
 	struct cifsInodeInfo *pCifsInode;
 	int disposition = FILE_OVERWRITE_IF;
-	int write_only = FALSE;
+	bool write_only = false;
 
 	xid = GetXid();
 
@@ -152,7 +153,7 @@
 		if (oflags & FMODE_WRITE) {
 			desiredAccess |= GENERIC_WRITE;
 			if (!(oflags & FMODE_READ))
-				write_only = TRUE;
+				write_only = true;
 		}
 
 		if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
@@ -176,9 +177,19 @@
 		FreeXid(xid);
 		return -ENOMEM;
 	}
+
+	mode &= ~current->fs->umask;
+
+	/*
+	 * if we're not using unix extensions, see if we need to set
+	 * ATTR_READONLY on the create call
+	 */
+	if (!pTcon->unix_ext && (mode & S_IWUGO) == 0)
+		create_options |= CREATE_OPTION_READONLY;
+
 	if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
 		rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
-			 desiredAccess, CREATE_NOT_DIR,
+			 desiredAccess, create_options,
 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	else
@@ -187,7 +198,7 @@
 	if (rc == -EIO) {
 		/* old server, retry the open legacy style */
 		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
-			desiredAccess, CREATE_NOT_DIR,
+			desiredAccess, create_options,
 			&fileHandle, &oplock, buf, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	}
@@ -197,7 +208,6 @@
 		/* If Open reported that we actually created a file
 		then we now have to set the mode if possible */
 		if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
-			mode &= ~current->fs->umask;
 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
 					(__u64)current->fsuid,
@@ -254,7 +264,7 @@
 			d_instantiate(direntry, newinode);
 		}
 		if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
-			((nd->flags & LOOKUP_OPEN) == FALSE)) {
+			(!(nd->flags & LOOKUP_OPEN))) {
 			/* mknod case - do not leave file open */
 			CIFSSMBClose(xid, pTcon, fileHandle);
 		} else if (newinode) {
@@ -266,8 +276,8 @@
 			pCifsFile->netfid = fileHandle;
 			pCifsFile->pid = current->tgid;
 			pCifsFile->pInode = newinode;
-			pCifsFile->invalidHandle = FALSE;
-			pCifsFile->closePend     = FALSE;
+			pCifsFile->invalidHandle = false;
+			pCifsFile->closePend     = false;
 			init_MUTEX(&pCifsFile->fh_sem);
 			mutex_init(&pCifsFile->lock_mutex);
 			INIT_LIST_HEAD(&pCifsFile->llist);
@@ -280,7 +290,7 @@
 			pCifsInode = CIFS_I(newinode);
 			if (pCifsInode) {
 				/* if readable file instance put first in list*/
-				if (write_only == TRUE) {
+				if (write_only) {
 					list_add_tail(&pCifsFile->flist,
 						&pCifsInode->openFileList);
 				} else {
@@ -288,12 +298,12 @@
 						&pCifsInode->openFileList);
 				}
 				if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-					pCifsInode->clientCanCacheAll = TRUE;
-					pCifsInode->clientCanCacheRead = TRUE;
+					pCifsInode->clientCanCacheAll = true;
+					pCifsInode->clientCanCacheRead = true;
 					cFYI(1, ("Exclusive Oplock inode %p",
 						newinode));
 				} else if ((oplock & 0xF) == OPLOCK_READ)
-					pCifsInode->clientCanCacheRead = TRUE;
+					pCifsInode->clientCanCacheRead = true;
 			}
 			write_unlock(&GlobalSMBSeslock);
 		}
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 7cc86c4..939e256 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -55,6 +55,32 @@
 	.match       = user_match,
 };
 
+/* Checks if supplied name is IP address
+ * returns:
+ * 		1 - name is IP
+ * 		0 - name is not IP
+ */
+static int is_ip(const char *name)
+{
+	int rc;
+	struct sockaddr_in sin_server;
+	struct sockaddr_in6 sin_server6;
+
+	rc = cifs_inet_pton(AF_INET, name,
+			&sin_server.sin_addr.s_addr);
+
+	if (rc <= 0) {
+		/* not ipv4 address, try ipv6 */
+		rc = cifs_inet_pton(AF_INET6, name,
+				&sin_server6.sin6_addr.in6_u);
+		if (rc > 0)
+			return 1;
+	} else {
+		return 1;
+	}
+	/* we failed translating address */
+	return 0;
+}
 
 /* Resolves server name to ip address.
  * input:
@@ -67,8 +93,9 @@
 dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
 {
 	int rc = -EAGAIN;
-	struct key *rkey;
+	struct key *rkey = ERR_PTR(-EAGAIN);
 	char *name;
+	char *data = NULL;
 	int len;
 
 	if (!ip_addr || !unc)
@@ -97,26 +124,41 @@
 	memcpy(name, unc+2, len);
 	name[len] = 0;
 
+	if (is_ip(name)) {
+		cFYI(1, ("%s: it is IP, skipping dns upcall: %s",
+					__func__, name));
+		data = name;
+		goto skip_upcall;
+	}
+
 	rkey = request_key(&key_type_dns_resolver, name, "");
 	if (!IS_ERR(rkey)) {
-		len = strlen(rkey->payload.data);
-		*ip_addr = kmalloc(len+1, GFP_KERNEL);
-		if (*ip_addr) {
-			memcpy(*ip_addr, rkey->payload.data, len);
-			(*ip_addr)[len] = '\0';
-			cFYI(1, ("%s: resolved: %s to %s", __func__,
+		data = rkey->payload.data;
+		cFYI(1, ("%s: resolved: %s to %s", __func__,
 					rkey->description,
 					*ip_addr
 				));
+	} else {
+		cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+		goto out;
+	}
+
+skip_upcall:
+	if (data) {
+		len = strlen(data);
+		*ip_addr = kmalloc(len+1, GFP_KERNEL);
+		if (*ip_addr) {
+			memcpy(*ip_addr, data, len);
+			(*ip_addr)[len] = '\0';
 			rc = 0;
 		} else {
 			rc = -ENOMEM;
 		}
-		key_put(rkey);
-	} else {
-		cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+		if (!IS_ERR(rkey))
+			key_put(rkey);
 	}
 
+out:
 	kfree(name);
 	return rc;
 }
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index 7d1d5aa..5a57581 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -68,7 +68,7 @@
 {
 	int xid;
 	int rc = -EINVAL;
-	int oplock = FALSE;
+	int oplock = 0;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
 	char *full_path = NULL;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 40b6900..31a0a33 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -51,8 +51,8 @@
 	INIT_LIST_HEAD(&private_data->llist);
 	private_data->pfile = file; /* needed for writepage */
 	private_data->pInode = inode;
-	private_data->invalidHandle = FALSE;
-	private_data->closePend = FALSE;
+	private_data->invalidHandle = false;
+	private_data->closePend = false;
 	/* we have to track num writers to the inode, since writepages
 	does not tell us which handle the write is for so there can
 	be a close (overlapping with write) of the filehandle that
@@ -148,12 +148,12 @@
 			full_path, buf, inode->i_sb, xid, NULL);
 
 	if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-		pCifsInode->clientCanCacheAll = TRUE;
-		pCifsInode->clientCanCacheRead = TRUE;
+		pCifsInode->clientCanCacheAll = true;
+		pCifsInode->clientCanCacheRead = true;
 		cFYI(1, ("Exclusive Oplock granted on inode %p",
 			 file->f_path.dentry->d_inode));
 	} else if ((*oplock & 0xF) == OPLOCK_READ)
-		pCifsInode->clientCanCacheRead = TRUE;
+		pCifsInode->clientCanCacheRead = true;
 
 	return rc;
 }
@@ -247,7 +247,7 @@
 	if (oplockEnabled)
 		oplock = REQ_OPLOCK;
 	else
-		oplock = FALSE;
+		oplock = 0;
 
 	/* BB pass O_SYNC flag through on file attributes .. BB */
 
@@ -339,7 +339,7 @@
 	return rc;
 }
 
-static int cifs_reopen_file(struct file *file, int can_flush)
+static int cifs_reopen_file(struct file *file, bool can_flush)
 {
 	int rc = -EACCES;
 	int xid, oplock;
@@ -360,7 +360,7 @@
 
 	xid = GetXid();
 	down(&pCifsFile->fh_sem);
-	if (pCifsFile->invalidHandle == FALSE) {
+	if (!pCifsFile->invalidHandle) {
 		up(&pCifsFile->fh_sem);
 		FreeXid(xid);
 		return 0;
@@ -404,7 +404,7 @@
 	if (oplockEnabled)
 		oplock = REQ_OPLOCK;
 	else
-		oplock = FALSE;
+		oplock = 0;
 
 	/* Can not refresh inode by passing in file_info buf to be returned
 	   by SMBOpen and then calling get_inode_info with returned buf
@@ -422,7 +422,7 @@
 		cFYI(1, ("oplock: %d", oplock));
 	} else {
 		pCifsFile->netfid = netfid;
-		pCifsFile->invalidHandle = FALSE;
+		pCifsFile->invalidHandle = false;
 		up(&pCifsFile->fh_sem);
 		pCifsInode = CIFS_I(inode);
 		if (pCifsInode) {
@@ -432,8 +432,8 @@
 					CIFS_I(inode)->write_behind_rc = rc;
 			/* temporarily disable caching while we
 			   go to server to get inode info */
-				pCifsInode->clientCanCacheAll = FALSE;
-				pCifsInode->clientCanCacheRead = FALSE;
+				pCifsInode->clientCanCacheAll = false;
+				pCifsInode->clientCanCacheRead = false;
 				if (pTcon->unix_ext)
 					rc = cifs_get_inode_info_unix(&inode,
 						full_path, inode->i_sb, xid);
@@ -448,16 +448,16 @@
 			     we can not go to the server to get the new inod
 			     info */
 			if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-				pCifsInode->clientCanCacheAll = TRUE;
-				pCifsInode->clientCanCacheRead = TRUE;
+				pCifsInode->clientCanCacheAll = true;
+				pCifsInode->clientCanCacheRead = true;
 				cFYI(1, ("Exclusive Oplock granted on inode %p",
 					 file->f_path.dentry->d_inode));
 			} else if ((oplock & 0xF) == OPLOCK_READ) {
-				pCifsInode->clientCanCacheRead = TRUE;
-				pCifsInode->clientCanCacheAll = FALSE;
+				pCifsInode->clientCanCacheRead = true;
+				pCifsInode->clientCanCacheAll = false;
 			} else {
-				pCifsInode->clientCanCacheRead = FALSE;
-				pCifsInode->clientCanCacheAll = FALSE;
+				pCifsInode->clientCanCacheRead = false;
+				pCifsInode->clientCanCacheAll = false;
 			}
 			cifs_relock_file(pCifsFile);
 		}
@@ -484,7 +484,7 @@
 	if (pSMBFile) {
 		struct cifsLockInfo *li, *tmp;
 
-		pSMBFile->closePend = TRUE;
+		pSMBFile->closePend = true;
 		if (pTcon) {
 			/* no sense reconnecting to close a file that is
 			   already closed */
@@ -553,8 +553,8 @@
 		cFYI(1, ("closing last open instance for inode %p", inode));
 		/* if the file is not open we do not know if we can cache info
 		   on this inode, much less write behind and read ahead */
-		CIFS_I(inode)->clientCanCacheRead = FALSE;
-		CIFS_I(inode)->clientCanCacheAll  = FALSE;
+		CIFS_I(inode)->clientCanCacheRead = false;
+		CIFS_I(inode)->clientCanCacheAll  = false;
 	}
 	read_unlock(&GlobalSMBSeslock);
 	if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
@@ -583,9 +583,9 @@
 		pTcon = cifs_sb->tcon;
 
 		cFYI(1, ("Freeing private data in close dir"));
-		if ((pCFileStruct->srch_inf.endOfSearch == FALSE) &&
-		   (pCFileStruct->invalidHandle == FALSE)) {
-			pCFileStruct->invalidHandle = TRUE;
+		if (!pCFileStruct->srch_inf.endOfSearch &&
+		    !pCFileStruct->invalidHandle) {
+			pCFileStruct->invalidHandle = true;
 			rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
 			cFYI(1, ("Closing uncompleted readdir with rc %d",
 				 rc));
@@ -637,12 +637,12 @@
 	__u32 numLock = 0;
 	__u32 numUnlock = 0;
 	__u64 length;
-	int wait_flag = FALSE;
+	bool wait_flag = false;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
 	__u16 netfid;
 	__u8 lockType = LOCKING_ANDX_LARGE_FILES;
-	int posix_locking;
+	bool posix_locking;
 
 	length = 1 + pfLock->fl_end - pfLock->fl_start;
 	rc = -EACCES;
@@ -659,7 +659,7 @@
 		cFYI(1, ("Flock"));
 	if (pfLock->fl_flags & FL_SLEEP) {
 		cFYI(1, ("Blocking lock"));
-		wait_flag = TRUE;
+		wait_flag = true;
 	}
 	if (pfLock->fl_flags & FL_ACCESS)
 		cFYI(1, ("Process suspended by mandatory locking - "
@@ -794,7 +794,7 @@
 					stored_rc = CIFSSMBLock(xid, pTcon,
 							netfid,
 							li->length, li->offset,
-							1, 0, li->type, FALSE);
+							1, 0, li->type, false);
 					if (stored_rc)
 						rc = stored_rc;
 
@@ -866,7 +866,7 @@
 				   filemap_fdatawait from here so tell
 				   reopen_file not to flush data to server
 				   now */
-				rc = cifs_reopen_file(file, FALSE);
+				rc = cifs_reopen_file(file, false);
 				if (rc != 0)
 					break;
 			}
@@ -966,7 +966,7 @@
 				   filemap_fdatawait from here so tell
 				   reopen_file not to flush data to
 				   server now */
-				rc = cifs_reopen_file(file, FALSE);
+				rc = cifs_reopen_file(file, false);
 				if (rc != 0)
 					break;
 			}
@@ -1093,7 +1093,7 @@
 
 			read_unlock(&GlobalSMBSeslock);
 			/* Had to unlock since following call can block */
-			rc = cifs_reopen_file(open_file->pfile, FALSE);
+			rc = cifs_reopen_file(open_file->pfile, false);
 			if (!rc) {
 				if (!open_file->closePend)
 					return open_file;
@@ -1608,7 +1608,7 @@
 			int buf_type = CIFS_NO_BUFFER;
 			if ((open_file->invalidHandle) &&
 			    (!open_file->closePend)) {
-				rc = cifs_reopen_file(file, TRUE);
+				rc = cifs_reopen_file(file, true);
 				if (rc != 0)
 					break;
 			}
@@ -1693,7 +1693,7 @@
 		while (rc == -EAGAIN) {
 			if ((open_file->invalidHandle) &&
 			    (!open_file->closePend)) {
-				rc = cifs_reopen_file(file, TRUE);
+				rc = cifs_reopen_file(file, true);
 				if (rc != 0)
 					break;
 			}
@@ -1850,7 +1850,7 @@
 		while (rc == -EAGAIN) {
 			if ((open_file->invalidHandle) &&
 			    (!open_file->closePend)) {
-				rc = cifs_reopen_file(file, TRUE);
+				rc = cifs_reopen_file(file, true);
 				if (rc != 0)
 					break;
 			}
@@ -2009,10 +2009,10 @@
    refreshing the inode only on increases in the file size
    but this is tricky to do without racing with writebehind
    page caching in the current Linux kernel design */
-int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
+bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
 {
 	if (!cifsInode)
-		return 1;
+		return true;
 
 	if (is_inode_writable(cifsInode)) {
 		/* This inode is open for write at least once */
@@ -2022,15 +2022,15 @@
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
 			/* since no page cache to corrupt on directio
 			we can change size safely */
-			return 1;
+			return true;
 		}
 
 		if (i_size_read(&cifsInode->vfs_inode) < end_of_file)
-			return 1;
+			return true;
 
-		return 0;
+		return false;
 	} else
-		return 1;
+		return true;
 }
 
 static int cifs_prepare_write(struct file *file, struct page *page,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index e1031b9..fcbdbb6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -281,7 +281,7 @@
 			    struct cifs_sb_info *cifs_sb, int xid)
 {
 	int rc;
-	int oplock = FALSE;
+	int oplock = 0;
 	__u16 netfid;
 	struct cifsTconInfo *pTcon = cifs_sb->tcon;
 	char buf[24];
@@ -389,7 +389,7 @@
 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 	const unsigned char *full_path = NULL;
 	char *buf = NULL;
-	int adjustTZ = FALSE;
+	bool adjustTZ = false;
 	bool is_dfs_referral = false;
 
 	pTcon = cifs_sb->tcon;
@@ -425,7 +425,7 @@
 					pfindData, cifs_sb->local_nls,
 					cifs_sb->mnt_cifs_flags &
 					  CIFS_MOUNT_MAP_SPECIAL_CHR);
-			adjustTZ = TRUE;
+			adjustTZ = true;
 		}
 	}
 	/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
@@ -703,7 +703,7 @@
 	} else if (rc == -ENOENT) {
 		d_drop(direntry);
 	} else if (rc == -ETXTBSY) {
-		int oplock = FALSE;
+		int oplock = 0;
 		__u16 netfid;
 
 		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
@@ -736,7 +736,7 @@
 				rc = -EOPNOTSUPP;
 
 			if (rc == -EOPNOTSUPP) {
-				int oplock = FALSE;
+				int oplock = 0;
 				__u16 netfid;
 			/*	rc = CIFSSMBSetAttrLegacy(xid, pTcon,
 							  full_path,
@@ -774,7 +774,7 @@
 				if (direntry->d_inode)
 					drop_nlink(direntry->d_inode);
 			} else if (rc == -ETXTBSY) {
-				int oplock = FALSE;
+				int oplock = 0;
 				__u16 netfid;
 
 				rc = CIFSSMBOpen(xid, pTcon, full_path,
@@ -974,8 +974,8 @@
 		  * failed to get it from the server or was set bogus */
 		if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
 				direntry->d_inode->i_nlink = 2;
+		mode &= ~current->fs->umask;
 		if (pTcon->unix_ext) {
-			mode &= ~current->fs->umask;
 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 						    mode,
@@ -994,9 +994,16 @@
 						    CIFS_MOUNT_MAP_SPECIAL_CHR);
 			}
 		} else {
-			/* BB to be implemented via Windows secrty descriptors
-			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
-						 -1, -1, local_nls); */
+			if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
+			    (mode & S_IWUGO) == 0) {
+				FILE_BASIC_INFO pInfo;
+				memset(&pInfo, 0, sizeof(pInfo));
+				pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
+				CIFSSMBSetTimes(xid, pTcon, full_path,
+						&pInfo, cifs_sb->local_nls,
+						cifs_sb->mnt_cifs_flags &
+						CIFS_MOUNT_MAP_SPECIAL_CHR);
+			}
 			if (direntry->d_inode) {
 				direntry->d_inode->i_mode = mode;
 				direntry->d_inode->i_mode |= S_IFDIR;
@@ -1149,7 +1156,7 @@
 		cFYI(1, ("rename rc %d", rc));
 
 	if ((rc == -EIO) || (rc == -EEXIST)) {
-		int oplock = FALSE;
+		int oplock = 0;
 		__u16 netfid;
 
 		/* BB FIXME Is Generic Read correct for rename? */
@@ -1186,7 +1193,7 @@
 	struct cifsInodeInfo *cifsInode;
 	loff_t local_size;
 	struct timespec local_mtime;
-	int invalidate_inode = FALSE;
+	bool invalidate_inode = false;
 
 	if (direntry->d_inode == NULL)
 		return -ENOENT;
@@ -1268,7 +1275,7 @@
 			   only ones who could have modified the file and the
 			   server copy is staler than ours */
 		} else {
-			invalidate_inode = TRUE;
+			invalidate_inode = true;
 		}
 	}
 
@@ -1402,24 +1409,25 @@
 	int rc = -EACCES;
 	struct cifsFileInfo *open_file = NULL;
 	FILE_BASIC_INFO time_buf;
-	int set_time = FALSE;
-	int set_dosattr = FALSE;
+	bool set_time = false;
+	bool set_dosattr = false;
 	__u64 mode = 0xFFFFFFFFFFFFFFFFULL;
 	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
 	__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
 	struct cifsInodeInfo *cifsInode;
+	struct inode *inode = direntry->d_inode;
 
 	xid = GetXid();
 
 	cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
 		 direntry->d_name.name, attrs->ia_valid));
 
-	cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
+	cifs_sb = CIFS_SB(inode->i_sb);
 	pTcon = cifs_sb->tcon;
 
 	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
 		/* check if we have permission to change attrs */
-		rc = inode_change_ok(direntry->d_inode, attrs);
+		rc = inode_change_ok(inode, attrs);
 		if (rc < 0) {
 			FreeXid(xid);
 			return rc;
@@ -1432,7 +1440,7 @@
 		FreeXid(xid);
 		return -ENOMEM;
 	}
-	cifsInode = CIFS_I(direntry->d_inode);
+	cifsInode = CIFS_I(inode);
 
 	if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
 		/*
@@ -1443,9 +1451,9 @@
 		   will be truncated anyway? Also, should we error out here if
 		   the flush returns error?
 		 */
-		rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
+		rc = filemap_write_and_wait(inode->i_mapping);
 		if (rc != 0) {
-			CIFS_I(direntry->d_inode)->write_behind_rc = rc;
+			cifsInode->write_behind_rc = rc;
 			rc = 0;
 		}
 	}
@@ -1464,7 +1472,7 @@
 			__u16 nfid = open_file->netfid;
 			__u32 npid = open_file->pid;
 			rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
-						nfid, npid, FALSE);
+						nfid, npid, false);
 			atomic_dec(&open_file->wrtPending);
 			cFYI(1, ("SetFSize for attrs rc = %d", rc));
 			if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
@@ -1484,14 +1492,14 @@
 			   it was found or because there was an error setting
 			   it by handle */
 			rc = CIFSSMBSetEOF(xid, pTcon, full_path,
-					   attrs->ia_size, FALSE,
+					   attrs->ia_size, false,
 					   cifs_sb->local_nls,
 					   cifs_sb->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 			cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
 			if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 				__u16 netfid;
-				int oplock = FALSE;
+				int oplock = 0;
 
 				rc = SMBLegacyOpen(xid, pTcon, full_path,
 					FILE_OPEN,
@@ -1516,14 +1524,13 @@
 
 		/* Server is ok setting allocation size implicitly - no need
 		   to call:
-		CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE,
+		CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true,
 			 cifs_sb->local_nls);
 		   */
 
 		if (rc == 0) {
-			rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
-			cifs_truncate_page(direntry->d_inode->i_mapping,
-					   direntry->d_inode->i_size);
+			rc = cifs_vmtruncate(inode, attrs->ia_size);
+			cifs_truncate_page(inode->i_mapping, inode->i_size);
 		} else
 			goto cifs_setattr_exit;
 	}
@@ -1557,14 +1564,14 @@
 		rc = 0;
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
-			rc = mode_to_acl(direntry->d_inode, full_path, mode);
+			rc = mode_to_acl(inode, full_path, mode);
 		else if ((mode & S_IWUGO) == 0) {
 #else
 		if ((mode & S_IWUGO) == 0) {
 #endif
 			/* not writeable */
 			if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
-				set_dosattr = TRUE;
+				set_dosattr = true;
 				time_buf.Attributes =
 					cpu_to_le32(cifsInode->cifsAttrs |
 						    ATTR_READONLY);
@@ -1574,28 +1581,24 @@
 			not be able to write to it - so if any write
 			bit is enabled for user or group or other we
 			need to at least try to remove r/o dos attr */
-			set_dosattr = TRUE;
+			set_dosattr = true;
 			time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
 					    (~ATTR_READONLY));
 			/* Windows ignores set to zero */
 			if (time_buf.Attributes == 0)
 				time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
 		}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
-			mode_to_acl(direntry->d_inode, full_path, mode);
-#endif
 	}
 
 	if (attrs->ia_valid & ATTR_ATIME) {
-		set_time = TRUE;
+		set_time = true;
 		time_buf.LastAccessTime =
 		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
 	} else
 		time_buf.LastAccessTime = 0;
 
 	if (attrs->ia_valid & ATTR_MTIME) {
-		set_time = TRUE;
+		set_time = true;
 		time_buf.LastWriteTime =
 		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
 	} else
@@ -1606,7 +1609,7 @@
 	   server times */
 
 	if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
-		set_time = TRUE;
+		set_time = true;
 		/* Although Samba throws this field away
 		it may be useful to Windows - but we do
 		not want to set ctime unless some other
@@ -1630,7 +1633,7 @@
 			rc = -EOPNOTSUPP;
 
 		if (rc == -EOPNOTSUPP) {
-			int oplock = FALSE;
+			int oplock = 0;
 			__u16 netfid;
 
 			cFYI(1, ("calling SetFileInfo since SetPathInfo for "
@@ -1669,7 +1672,7 @@
 	/* do not need local check to inode_check_ok since the server does
 	   that */
 	if (!rc)
-		rc = inode_setattr(direntry->d_inode, attrs);
+		rc = inode_setattr(inode, attrs);
 cifs_setattr_exit:
 	kfree(full_path);
 	FreeXid(xid);
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index d4e7ec9..1c2c3ce 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -230,7 +230,7 @@
 	struct inode *inode = direntry->d_inode;
 	int rc = -EACCES;
 	int xid;
-	int oplock = FALSE;
+	int oplock = 0;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
 	char *full_path = NULL;
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 2a42d9f..1d69b80 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -496,7 +496,8 @@
 	}
 	return 0;
 }
-int
+
+bool
 is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
 {
 	struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
@@ -522,17 +523,17 @@
 				pnotify->Action));  /* BB removeme BB */
 			/*   cifs_dump_mem("Rcvd notify Data: ",buf,
 				sizeof(struct smb_hdr)+60); */
-			return TRUE;
+			return true;
 		}
 		if (pSMBr->hdr.Status.CifsError) {
 			cFYI(1, ("notify err 0x%d",
 				pSMBr->hdr.Status.CifsError));
-			return TRUE;
+			return true;
 		}
-		return FALSE;
+		return false;
 	}
 	if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
-		return FALSE;
+		return false;
 	if (pSMB->hdr.Flags & SMBFLG_RESPONSE) {
 		/* no sense logging error on invalid handle on oplock
 		   break - harmless race between close request and oplock
@@ -541,21 +542,21 @@
 		if ((NT_STATUS_INVALID_HANDLE) ==
 		   le32_to_cpu(pSMB->hdr.Status.CifsError)) {
 			cFYI(1, ("invalid handle on oplock break"));
-			return TRUE;
+			return true;
 		} else if (ERRbadfid ==
 		   le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
-			return TRUE;
+			return true;
 		} else {
-			return FALSE; /* on valid oplock brk we get "request" */
+			return false; /* on valid oplock brk we get "request" */
 		}
 	}
 	if (pSMB->hdr.WordCount != 8)
-		return FALSE;
+		return false;
 
 	cFYI(1, ("oplock type 0x%d level 0x%d",
 		 pSMB->LockType, pSMB->OplockLevel));
 	if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
-		return FALSE;
+		return false;
 
 	/* look up tcon based on tid & uid */
 	read_lock(&GlobalSMBSeslock);
@@ -573,11 +574,11 @@
 					    ("file id match, oplock break"));
 					pCifsInode =
 						CIFS_I(netfile->pInode);
-					pCifsInode->clientCanCacheAll = FALSE;
+					pCifsInode->clientCanCacheAll = false;
 					if (pSMB->OplockLevel == 0)
 						pCifsInode->clientCanCacheRead
-							= FALSE;
-					pCifsInode->oplockPending = TRUE;
+							= false;
+					pCifsInode->oplockPending = true;
 					AllocOplockQEntry(netfile->pInode,
 							  netfile->netfid,
 							  tcon);
@@ -585,17 +586,17 @@
 					    ("about to wake up oplock thread"));
 					if (oplockThread)
 					    wake_up_process(oplockThread);
-					return TRUE;
+					return true;
 				}
 			}
 			read_unlock(&GlobalSMBSeslock);
 			cFYI(1, ("No matching file for oplock break"));
-			return TRUE;
+			return true;
 		}
 	}
 	read_unlock(&GlobalSMBSeslock);
 	cFYI(1, ("Can not process oplock break for non-existent connection"));
-	return TRUE;
+	return true;
 }
 
 void
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 3b5a5ce..00f4cff 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -132,47 +132,17 @@
 	{0, 0}
 };
 
-
-/* if the mount helper is missing we need to reverse the 1st slash
-   from '/' to backslash in order to format the UNC properly for
-   ip address parsing and for tree connect (unless the user
-   remembered to put the UNC name in properly). Fortunately we do
-   not have to call this twice (we check for IPv4 addresses
-   first, so it is already converted by the time we
-   try IPv6 addresses */
-static int canonicalize_unc(char *cp)
-{
-	int i;
-
-	for (i = 0; i <= 46 /* INET6_ADDRSTRLEN */ ; i++) {
-		if (cp[i] == 0)
-			break;
-		if (cp[i] == '\\')
-			break;
-		if (cp[i] == '/') {
-			cFYI(DBG2, ("change slash to \\ in malformed UNC"));
-			cp[i] = '\\';
-			return 1;
-		}
-	}
-	return 0;
-}
-
 /* Convert string containing dotted ip address to binary form */
 /* returns 0 if invalid address */
 
 int
-cifs_inet_pton(int address_family, char *cp, void *dst)
+cifs_inet_pton(const int address_family, const char *cp, void *dst)
 {
 	int ret = 0;
 
 	/* calculate length by finding first slash or NULL */
 	if (address_family == AF_INET) {
 		ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL);
-		if (ret == 0) {
-			if (canonicalize_unc(cp))
-				ret = in4_pton(cp, -1, dst, '\\', NULL);
-		}
 	} else if (address_family == AF_INET6) {
 		ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
 	}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 32b445e..34ec321 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -447,8 +447,8 @@
 	if (file->private_data == NULL)
 		return -ENOMEM;
 	cifsFile = file->private_data;
-	cifsFile->invalidHandle = TRUE;
-	cifsFile->srch_inf.endOfSearch = FALSE;
+	cifsFile->invalidHandle = true;
+	cifsFile->srch_inf.endOfSearch = false;
 
 	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
 	if (cifs_sb == NULL)
@@ -485,7 +485,7 @@
 		cifs_sb->mnt_cifs_flags &
 			CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
 	if (rc == 0)
-		cifsFile->invalidHandle = FALSE;
+		cifsFile->invalidHandle = false;
 	if ((rc == -EOPNOTSUPP) &&
 		(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
 		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
@@ -670,7 +670,7 @@
 	   (index_to_find < first_entry_in_buffer)) {
 		/* close and restart search */
 		cFYI(1, ("search backing up - close and restart search"));
-		cifsFile->invalidHandle = TRUE;
+		cifsFile->invalidHandle = true;
 		CIFSFindClose(xid, pTcon, cifsFile->netfid);
 		kfree(cifsFile->search_resume_name);
 		cifsFile->search_resume_name = NULL;
@@ -692,7 +692,7 @@
 	}
 
 	while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
-	      (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) {
+	      (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
 		cFYI(1, ("calling findnext2"));
 		rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
 				  &cifsFile->srch_inf);
@@ -1038,7 +1038,7 @@
 				break;
 			}
 		} /* else {
-			cifsFile->invalidHandle = TRUE;
+			cifsFile->invalidHandle = true;
 			CIFSFindClose(xid, pTcon, cifsFile->netfid);
 		}
 		kfree(cifsFile->search_resume_name);
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 58bbfd9..ff3232f 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -35,11 +35,11 @@
 #include "cifs_debug.h"
 #include "cifsencrypt.h"
 
-#ifndef FALSE
-#define FALSE 0
+#ifndef false
+#define false 0
 #endif
-#ifndef TRUE
-#define TRUE 1
+#ifndef true
+#define true 1
 #endif
 
 /* following came from the other byteorder.h to avoid include conflicts */
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 8cd6a44..e9527ee 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -264,7 +264,7 @@
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 		else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
 			__u16 fid;
-			int oplock = FALSE;
+			int oplock = 0;
 			struct cifs_ntsd *pacl = NULL;
 			__u32 buflen = 0;
 			if (experimEnabled)
diff --git a/fs/dquot.c b/fs/dquot.c
index dfba162..5ac77da 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1491,6 +1491,16 @@
 
 	/* We need to serialize quota_off() for device */
 	mutex_lock(&dqopt->dqonoff_mutex);
+
+	/*
+	 * Skip everything if there's nothing to do. We have to do this because
+	 * sometimes we are called when fill_super() failed and calling
+	 * sync_fs() in such cases does no good.
+	 */
+	if (!sb_any_quota_enabled(sb) && !sb_any_quota_suspended(sb)) {
+		mutex_unlock(&dqopt->dqonoff_mutex);
+		return 0;
+	}
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		toputinode[cnt] = NULL;
 		if (type != -1 && cnt != type)
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 0a13973..c92cc1c 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -37,17 +37,11 @@
 {
 	struct dentry *dir;
 
-	dir = dget(dentry->d_parent);
+	dir = dget_parent(dentry);
 	mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT);
 	return dir;
 }
 
-static void unlock_parent(struct dentry *dentry)
-{
-	mutex_unlock(&(dentry->d_parent->d_inode->i_mutex));
-	dput(dentry->d_parent);
-}
-
 static void unlock_dir(struct dentry *dir)
 {
 	mutex_unlock(&dir->d_inode->i_mutex);
@@ -426,8 +420,9 @@
 	int rc = 0;
 	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
+	struct dentry *lower_dir_dentry;
 
-	lock_parent(lower_dentry);
+	lower_dir_dentry = lock_parent(lower_dentry);
 	rc = vfs_unlink(lower_dir_inode, lower_dentry);
 	if (rc) {
 		printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
@@ -439,7 +434,7 @@
 	dentry->d_inode->i_ctime = dir->i_ctime;
 	d_drop(dentry);
 out_unlock:
-	unlock_parent(lower_dentry);
+	unlock_dir(lower_dir_dentry);
 	return rc;
 }
 
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index 788995e..6560da1 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -257,12 +257,14 @@
 	mutex_lock(&daemon->mux);
 	if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
 		rc = 0;
+		mutex_unlock(&ecryptfs_daemon_hash_mux);
 		printk(KERN_WARNING "%s: Attempt to read from zombified "
 		       "daemon\n", __func__);
 		goto out_unlock_daemon;
 	}
 	if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) {
 		rc = 0;
+		mutex_unlock(&ecryptfs_daemon_hash_mux);
 		goto out_unlock_daemon;
 	}
 	/* This daemon will not go away so long as this flag is set */
diff --git a/fs/exec.c b/fs/exec.c
index aeaa979..1f8a24a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -736,7 +736,7 @@
 	tsk->active_mm = mm;
 	activate_mm(active_mm, mm);
 	task_unlock(tsk);
-	mm_update_next_owner(mm);
+	mm_update_next_owner(old_mm);
 	arch_pick_mmap_layout(mm);
 	if (old_mm) {
 		up_read(&old_mm->mmap_sem);
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index d4a4f0e..175414a 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -1000,6 +1000,11 @@
 			i.value = NULL;
 			error = ext3_xattr_block_set(handle, inode, &i, &bs);
 		} else if (error == -ENOSPC) {
+			if (EXT3_I(inode)->i_file_acl && !bs.s.base) {
+				error = ext3_xattr_block_find(inode, &i, &bs);
+				if (error)
+					goto cleanup;
+			}
 			error = ext3_xattr_block_set(handle, inode, &i, &bs);
 			if (error)
 				goto cleanup;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index fbec2ef..b128bdc 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2639,8 +2639,7 @@
 	struct proc_dir_entry *proc;
 	char devname[64];
 
-	snprintf(devname, sizeof(devname) - 1, "%s",
-		bdevname(sb->s_bdev, devname));
+	bdevname(sb->s_bdev, devname);
 	sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4);
 
 	MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats);
@@ -2674,8 +2673,7 @@
 	if (sbi->s_mb_proc == NULL)
 		return -EINVAL;
 
-	snprintf(devname, sizeof(devname) - 1, "%s",
-		bdevname(sb->s_bdev, devname));
+	bdevname(sb->s_bdev, devname);
 	remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
 	remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
 	remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 3fbc2c6..ff08633 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1009,6 +1009,11 @@
 			i.value = NULL;
 			error = ext4_xattr_block_set(handle, inode, &i, &bs);
 		} else if (error == -ENOSPC) {
+			if (EXT4_I(inode)->i_file_acl && !bs.s.base) {
+				error = ext4_xattr_block_find(inode, &i, &bs);
+				if (error)
+					goto cleanup;
+			}
 			error = ext4_xattr_block_set(handle, inode, &i, &bs);
 			if (error)
 				goto cleanup;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f28cf8b..8092f0d 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -804,6 +804,8 @@
 		if (offset == PAGE_CACHE_SIZE)
 			offset = 0;
 
+		if (!fc->big_writes)
+			break;
 	} while (iov_iter_count(ii) && count < fc->max_write &&
 		 req->num_pages < FUSE_MAX_PAGES_PER_REQ && offset == 0);
 
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index dadffa2..bae9486 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -404,6 +404,9 @@
 	/** Is bmap not implemented by fs? */
 	unsigned no_bmap : 1;
 
+	/** Do multi-page cached writes */
+	unsigned big_writes : 1;
+
 	/** The number of requests waiting for completion */
 	atomic_t num_waiting;
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 79b6158..fb77e09 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -576,6 +576,8 @@
 				fc->no_lock = 1;
 			if (arg->flags & FUSE_ATOMIC_O_TRUNC)
 				fc->atomic_o_trunc = 1;
+			if (arg->flags & FUSE_BIG_WRITES)
+				fc->big_writes = 1;
 		} else {
 			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 			fc->no_lock = 1;
@@ -599,7 +601,8 @@
 	arg->major = FUSE_KERNEL_VERSION;
 	arg->minor = FUSE_KERNEL_MINOR_VERSION;
 	arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
-	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC;
+	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
+		FUSE_BIG_WRITES;
 	req->in.h.opcode = FUSE_INIT;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(*arg);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index d53b2af..67e1c8b 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -65,6 +65,8 @@
 		BUG();
 		return 0;
 	}
+	if (!tree)
+		return 0;
 	if (tree->node_size >= PAGE_CACHE_SIZE) {
 		nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);
 		spin_lock(&tree->hash_lock);
diff --git a/fs/hppfs/Makefile b/fs/hppfs/Makefile
index 6890433..8a1f5034 100644
--- a/fs/hppfs/Makefile
+++ b/fs/hppfs/Makefile
@@ -1,9 +1,9 @@
 #
-# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 # Licensed under the GPL
 #
 
-hppfs-objs := hppfs_kern.o
+hppfs-objs := hppfs.o
 
 obj-y =
-obj-$(CONFIG_HPPFS) += hppfs.o
+obj-$(CONFIG_HPPFS) += $(hppfs-objs)
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs.c
similarity index 91%
rename from fs/hppfs/hppfs_kern.c
rename to fs/hppfs/hppfs.c
index 8601d8e..65077aa 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs.c
@@ -33,7 +33,7 @@
 };
 
 struct hppfs_inode_info {
-        struct dentry *proc_dentry;
+	struct dentry *proc_dentry;
 	struct inode vfs_inode;
 };
 
@@ -52,7 +52,7 @@
 	int i;
 
 	sb = dentry->d_sb;
-	if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
+	if (dentry->d_parent != sb->s_root)
 		return 0;
 
 	for (i = 0; i < dentry->d_name.len; i++) {
@@ -136,7 +136,7 @@
 }
 
 static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
-                                  struct nameidata *nd)
+				   struct nameidata *nd)
 {
 	struct dentry *proc_dentry, *new, *parent;
 	struct inode *inode;
@@ -254,6 +254,8 @@
 	int err;
 
 	if (hppfs->contents != NULL) {
+		int rem;
+
 		if (*ppos >= hppfs->len)
 			return 0;
 
@@ -267,8 +269,10 @@
 
 		if (off + count > hppfs->len)
 			count = hppfs->len - off;
-		copy_to_user(buf, &data->contents[off], count);
-		*ppos += count;
+		rem = copy_to_user(buf, &data->contents[off], count);
+		*ppos += count - rem;
+		if (rem > 0)
+			return -EFAULT;
 	} else if (hppfs->host_fd != -1) {
 		err = os_seek_file(hppfs->host_fd, *ppos);
 		if (err) {
@@ -285,21 +289,15 @@
 	return count;
 }
 
-static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
-			   loff_t *ppos)
+static ssize_t hppfs_write(struct file *file, const char __user *buf,
+			   size_t len, loff_t *ppos)
 {
 	struct hppfs_private *data = file->private_data;
 	struct file *proc_file = data->proc_file;
 	ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
-	int err;
 
 	write = proc_file->f_path.dentry->d_inode->i_fop->write;
-
-	proc_file->f_pos = file->f_pos;
-	err = (*write)(proc_file, buf, len, &proc_file->f_pos);
-	file->f_pos = proc_file->f_pos;
-
-	return err;
+	return (*write)(proc_file, buf, len, ppos);
 }
 
 static int open_host_sock(char *host_file, int *filter_out)
@@ -357,7 +355,7 @@
 
 	if (filter) {
 		while ((n = read_proc(proc_file, data->contents,
-				     sizeof(data->contents), NULL, 0)) > 0)
+				      sizeof(data->contents), NULL, 0)) > 0)
 			os_write_file(fd, data->contents, n);
 		err = os_shutdown_socket(fd, 0, 1);
 		if (err) {
@@ -429,8 +427,8 @@
 static int hppfs_open(struct inode *inode, struct file *file)
 {
 	struct hppfs_private *data;
-	struct dentry *proc_dentry;
 	struct vfsmount *proc_mnt;
+	struct dentry *proc_dentry;
 	char *host_file;
 	int err, fd, type, filter;
 
@@ -492,8 +490,8 @@
 static int hppfs_dir_open(struct inode *inode, struct file *file)
 {
 	struct hppfs_private *data;
-	struct dentry *proc_dentry;
 	struct vfsmount *proc_mnt;
+	struct dentry *proc_dentry;
 	int err;
 
 	err = -ENOMEM;
@@ -620,6 +618,9 @@
 
 void hppfs_delete_inode(struct inode *ino)
 {
+	dput(HPPFS_I(ino)->proc_dentry);
+	mntput(ino->i_sb->s_fs_info);
+
 	clear_inode(ino);
 }
 
@@ -628,69 +629,46 @@
 	kfree(HPPFS_I(inode));
 }
 
-static void hppfs_put_super(struct super_block *sb)
-{
-	mntput(sb->s_fs_info);
-}
-
 static const struct super_operations hppfs_sbops = {
 	.alloc_inode	= hppfs_alloc_inode,
 	.destroy_inode	= hppfs_destroy_inode,
 	.delete_inode	= hppfs_delete_inode,
 	.statfs		= hppfs_statfs,
-	.put_super	= hppfs_put_super,
 };
 
 static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
 			  int buflen)
 {
-	struct file *proc_file;
 	struct dentry *proc_dentry;
-	struct vfsmount *proc_mnt;
-	int ret;
 
 	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-	proc_mnt = dentry->d_sb->s_fs_info;
-
-	proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
-	if (IS_ERR(proc_file))
-		return PTR_ERR(proc_file);
-
-	ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
-
-	fput(proc_file);
-
-	return ret;
+	return proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer,
+						    buflen);
 }
 
-static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-	struct file *proc_file;
 	struct dentry *proc_dentry;
-	struct vfsmount *proc_mnt;
-	void *ret;
 
 	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-	proc_mnt = dentry->d_sb->s_fs_info;
 
-	proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
-	if (IS_ERR(proc_file))
-		return proc_file;
+	return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
+}
 
-	ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
-
-	fput(proc_file);
-
-	return ret;
+int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+	return generic_permission(inode, mask, NULL);
 }
 
 static const struct inode_operations hppfs_dir_iops = {
 	.lookup		= hppfs_lookup,
+	.permission	= hppfs_permission,
 };
 
 static const struct inode_operations hppfs_link_iops = {
 	.readlink	= hppfs_readlink,
 	.follow_link	= hppfs_follow_link,
+	.permission	= hppfs_permission,
 };
 
 static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
@@ -712,7 +690,7 @@
 		inode->i_fop = &hppfs_file_fops;
 	}
 
-	HPPFS_I(inode)->proc_dentry = dentry;
+	HPPFS_I(inode)->proc_dentry = dget(dentry);
 
 	inode->i_uid = proc_ino->i_uid;
 	inode->i_gid = proc_ino->i_gid;
@@ -725,7 +703,7 @@
 	inode->i_size = proc_ino->i_size;
 	inode->i_blocks = proc_ino->i_blocks;
 
-	return 0;
+	return inode;
 }
 
 static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
diff --git a/fs/inode.c b/fs/inode.c
index bf64781..c36d948 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1149,13 +1149,8 @@
 void iput(struct inode *inode)
 {
 	if (inode) {
-		const struct super_operations *op = inode->i_sb->s_op;
-
 		BUG_ON(inode->i_state == I_CLEAR);
 
-		if (op && op->put_inode)
-			op->put_inode(inode);
-
 		if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
 			iput_final(inode);
 	}
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index cd931ef..5a8ca61 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -470,7 +470,9 @@
 	 * transaction!  Now comes the tricky part: we need to write out
 	 * metadata.  Loop over the transaction's entire buffer list:
 	 */
+	spin_lock(&journal->j_state_lock);
 	commit_transaction->t_state = T_COMMIT;
+	spin_unlock(&journal->j_state_lock);
 
 	J_ASSERT(commit_transaction->t_nr_buffers <=
 		 commit_transaction->t_outstanding_credits);
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 53632e3..2e24567 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -901,7 +901,7 @@
 {
 	char name[BDEVNAME_SIZE];
 
-	snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
+	bdevname(journal->j_dev, name);
 	journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats);
 	if (journal->j_proc_entry) {
 		proc_create_data("history", S_IRUGO, journal->j_proc_entry,
@@ -915,7 +915,7 @@
 {
 	char name[BDEVNAME_SIZE];
 
-	snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
+	bdevname(journal->j_dev, name);
 	remove_proc_entry("info", journal->j_proc_entry);
 	remove_proc_entry("history", journal->j_proc_entry);
 	remove_proc_entry(name, proc_jbd2_stats);
diff --git a/fs/locks.c b/fs/locks.c
index 663c069..11dbf08 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -773,7 +773,7 @@
 	 * give it the opportunity to lock the file.
 	 */
 	if (found)
-		cond_resched();
+		cond_resched_bkl();
 
 find_conflict:
 	for_each_lock(inode, before) {
@@ -1753,6 +1753,7 @@
 	struct file_lock *file_lock = locks_alloc_lock();
 	struct flock flock;
 	struct inode *inode;
+	struct file *f;
 	int error;
 
 	if (file_lock == NULL)
@@ -1825,7 +1826,15 @@
 	 * Attempt to detect a close/fcntl race and recover by
 	 * releasing the lock that was just acquired.
 	 */
-	if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+	/*
+	 * we need that spin_lock here - it prevents reordering between
+	 * update of inode->i_flock and check for it done in close().
+	 * rcu_read_lock() wouldn't do.
+	 */
+	spin_lock(&current->files->file_lock);
+	f = fcheck(fd);
+	spin_unlock(&current->files->file_lock);
+	if (!error && f != filp && flock.l_type != F_UNLCK) {
 		flock.l_type = F_UNLCK;
 		goto again;
 	}
@@ -1881,6 +1890,7 @@
 	struct file_lock *file_lock = locks_alloc_lock();
 	struct flock64 flock;
 	struct inode *inode;
+	struct file *f;
 	int error;
 
 	if (file_lock == NULL)
@@ -1953,7 +1963,10 @@
 	 * Attempt to detect a close/fcntl race and recover by
 	 * releasing the lock that was just acquired.
 	 */
-	if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+	spin_lock(&current->files->file_lock);
+	f = fcheck(fd);
+	spin_unlock(&current->files->file_lock);
+	if (!error && f != filp && flock.l_type != F_UNLCK) {
 		flock.l_type = F_UNLCK;
 		goto again;
 	}
diff --git a/fs/pipe.c b/fs/pipe.c
index 3499f9f..ec228bc 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -17,6 +17,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/audit.h>
+#include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -1086,8 +1087,11 @@
 
 	error = do_pipe(fd);
 	if (!error) {
-		if (copy_to_user(fildes, fd, sizeof(fd)))
+		if (copy_to_user(fildes, fd, sizeof(fd))) {
+			sys_close(fd[0]);
+			sys_close(fd[1]);
 			error = -EFAULT;
+		}
 	}
 	return error;
 }
diff --git a/fs/proc/array.c b/fs/proc/array.c
index dca997a..9e3b8c3 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -298,6 +298,7 @@
 	render_cap_t(m, "CapInh:\t", &p->cap_inheritable);
 	render_cap_t(m, "CapPrm:\t", &p->cap_permitted);
 	render_cap_t(m, "CapEff:\t", &p->cap_effective);
+	render_cap_t(m, "CapBnd:\t", &p->cap_bset);
 }
 
 static inline void task_context_switch_counts(struct seq_file *m,
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index e2b8e76..88717c0 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -5,11 +5,9 @@
 #include <linux/highmem.h>
 #include <linux/ptrace.h>
 #include <linux/pagemap.h>
-#include <linux/ptrace.h>
 #include <linux/mempolicy.h>
 #include <linux/swap.h>
 #include <linux/swapops.h>
-#include <linux/seq_file.h>
 
 #include <asm/elf.h>
 #include <asm/uaccess.h>
diff --git a/fs/splice.c b/fs/splice.c
index 633f58e..7815003 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -811,24 +811,19 @@
 {
 	struct address_space *mapping = out->f_mapping;
 	struct inode *inode = mapping->host;
-	int killsuid, killpriv;
+	struct splice_desc sd = {
+		.total_len = len,
+		.flags = flags,
+		.pos = *ppos,
+		.u.file = out,
+	};
 	ssize_t ret;
-	int err = 0;
 
-	killpriv = security_inode_need_killpriv(out->f_path.dentry);
-	killsuid = should_remove_suid(out->f_path.dentry);
-	if (unlikely(killsuid || killpriv)) {
-		mutex_lock(&inode->i_mutex);
-		if (killpriv)
-			err = security_inode_killpriv(out->f_path.dentry);
-		if (!err && killsuid)
-			err = __remove_suid(out->f_path.dentry, killsuid);
-		mutex_unlock(&inode->i_mutex);
-		if (err)
-			return err;
-	}
-
-	ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
+	inode_double_lock(inode, pipe->inode);
+	ret = remove_suid(out->f_path.dentry);
+	if (likely(!ret))
+		ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
+	inode_double_unlock(inode, pipe->inode);
 	if (ret > 0) {
 		unsigned long nr_pages;
 
@@ -840,6 +835,8 @@
 		 * 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);
@@ -1075,7 +1072,7 @@
 
 	ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
 	if (ret > 0)
-		*ppos = sd.pos;
+		*ppos += ret;
 
 	return ret;
 }
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index a1c3a1f..8c0e4b9 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -419,12 +419,8 @@
  */
 int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
-	if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) {
-		printk(KERN_WARNING "sysfs: duplicate filename '%s' "
-		       "can not be created\n", sd->s_name);
-		WARN_ON(1);
+	if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
 		return -EEXIST;
-	}
 
 	sd->s_parent = sysfs_get(acxt->parent_sd);
 
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 2b34c8c..d3231947 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -32,6 +32,7 @@
 #include <linux/buffer_head.h>
 #include <linux/sched.h>
 #include <linux/crc-itu-t.h>
+#include <linux/exportfs.h>
 
 static inline int udf_match(int len1, const char *name1, int len2,
 			    const char *name2)
@@ -158,6 +159,8 @@
 	sector_t offset;
 	struct extent_position epos = {};
 	struct udf_inode_info *dinfo = UDF_I(dir);
+	int isdotdot = dentry->d_name.len == 2 &&
+		dentry->d_name.name[0] == '.' && dentry->d_name.name[1] == '.';
 
 	size = udf_ext0_offset(dir) + dir->i_size;
 	f_pos = udf_ext0_offset(dir);
@@ -225,6 +228,12 @@
 				continue;
 		}
 
+		if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) &&
+		    isdotdot) {
+			brelse(epos.bh);
+			return fi;
+		}
+
 		if (!lfi)
 			continue;
 
@@ -286,9 +295,8 @@
 		}
 	}
 	unlock_kernel();
-	d_add(dentry, inode);
 
-	return NULL;
+	return d_splice_alias(inode, dentry);
 }
 
 static struct fileIdentDesc *udf_add_entry(struct inode *dir,
@@ -307,7 +315,7 @@
 	uint16_t liu;
 	int block;
 	kernel_lb_addr eloc;
-	uint32_t elen;
+	uint32_t elen = 0;
 	sector_t offset;
 	struct extent_position epos = {};
 	struct udf_inode_info *dinfo;
@@ -398,7 +406,8 @@
 	}
 
 add:
-	if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
+	/* Is there any extent whose size we need to round up? */
+	if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) {
 		elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
 		if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
 			epos.offset -= sizeof(short_ad);
@@ -1232,6 +1241,134 @@
 	return retval;
 }
 
+static struct dentry *udf_get_parent(struct dentry *child)
+{
+	struct dentry *parent;
+	struct inode *inode = NULL;
+	struct dentry dotdot;
+	struct fileIdentDesc cfi;
+	struct udf_fileident_bh fibh;
+
+	dotdot.d_name.name = "..";
+	dotdot.d_name.len = 2;
+
+	lock_kernel();
+	if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi))
+		goto out_unlock;
+
+	if (fibh.sbh != fibh.ebh)
+		brelse(fibh.ebh);
+	brelse(fibh.sbh);
+
+	inode = udf_iget(child->d_inode->i_sb,
+			 lelb_to_cpu(cfi.icb.extLocation));
+	if (!inode)
+		goto out_unlock;
+	unlock_kernel();
+
+	parent = d_alloc_anon(inode);
+	if (!parent) {
+		iput(inode);
+		parent = ERR_PTR(-ENOMEM);
+	}
+
+	return parent;
+out_unlock:
+	unlock_kernel();
+	return ERR_PTR(-EACCES);
+}
+
+
+static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
+					u16 partref, __u32 generation)
+{
+	struct inode *inode;
+	struct dentry *result;
+	kernel_lb_addr loc;
+
+	if (block == 0)
+		return ERR_PTR(-ESTALE);
+
+	loc.logicalBlockNum = block;
+	loc.partitionReferenceNum = partref;
+	inode = udf_iget(sb, loc);
+
+	if (inode == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	if (generation && inode->i_generation != generation) {
+		iput(inode);
+		return ERR_PTR(-ESTALE);
+	}
+	result = d_alloc_anon(inode);
+	if (!result) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	return result;
+}
+
+static struct dentry *udf_fh_to_dentry(struct super_block *sb,
+				       struct fid *fid, int fh_len, int fh_type)
+{
+	if ((fh_len != 3 && fh_len != 5) ||
+	    (fh_type != FILEID_UDF_WITH_PARENT &&
+	     fh_type != FILEID_UDF_WITHOUT_PARENT))
+		return NULL;
+
+	return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref,
+			fid->udf.generation);
+}
+
+static struct dentry *udf_fh_to_parent(struct super_block *sb,
+				       struct fid *fid, int fh_len, int fh_type)
+{
+	if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT)
+		return NULL;
+
+	return udf_nfs_get_inode(sb, fid->udf.parent_block,
+				 fid->udf.parent_partref,
+				 fid->udf.parent_generation);
+}
+static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
+			 int connectable)
+{
+	int len = *lenp;
+	struct inode *inode =  de->d_inode;
+	kernel_lb_addr location = UDF_I(inode)->i_location;
+	struct fid *fid = (struct fid *)fh;
+	int type = FILEID_UDF_WITHOUT_PARENT;
+
+	if (len < 3 || (connectable && len < 5))
+		return 255;
+
+	*lenp = 3;
+	fid->udf.block = location.logicalBlockNum;
+	fid->udf.partref = location.partitionReferenceNum;
+	fid->udf.generation = inode->i_generation;
+
+	if (connectable && !S_ISDIR(inode->i_mode)) {
+		spin_lock(&de->d_lock);
+		inode = de->d_parent->d_inode;
+		location = UDF_I(inode)->i_location;
+		fid->udf.parent_block = location.logicalBlockNum;
+		fid->udf.parent_partref = location.partitionReferenceNum;
+		fid->udf.parent_generation = inode->i_generation;
+		spin_unlock(&de->d_lock);
+		*lenp = 5;
+		type = FILEID_UDF_WITH_PARENT;
+	}
+
+	return type;
+}
+
+const struct export_operations udf_export_ops = {
+	.encode_fh	= udf_encode_fh,
+	.fh_to_dentry   = udf_fh_to_dentry,
+	.fh_to_parent   = udf_fh_to_parent,
+	.get_parent     = udf_get_parent,
+};
+
 const struct inode_operations udf_dir_inode_operations = {
 	.lookup				= udf_lookup,
 	.create				= udf_create,
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 63610f0..96dfd20 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -27,8 +27,8 @@
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
 
-inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
-			       uint16_t partition, uint32_t offset)
+uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
+			uint16_t partition, uint32_t offset)
 {
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct udf_part_map *map;
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 9fb18a3..7a5f69b 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1933,6 +1933,7 @@
 
 	/* Fill in the rest of the superblock */
 	sb->s_op = &udf_sb_ops;
+	sb->s_export_op = &udf_export_ops;
 	sb->dq_op = NULL;
 	sb->s_dirt = 0;
 	sb->s_magic = UDF_SUPER_MAGIC;
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index f3f45d0..8fa9c2d 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -73,6 +73,7 @@
 struct buffer_head;
 struct super_block;
 
+extern const struct export_operations udf_export_ops;
 extern const struct inode_operations udf_dir_inode_operations;
 extern const struct file_operations udf_dir_operations;
 extern const struct inode_operations udf_file_inode_operations;
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 244a1aa..11c0351 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -107,7 +107,6 @@
 
 /* inode.c */
 extern struct inode *ufs_iget(struct super_block *, unsigned long);
-extern void ufs_put_inode (struct inode *);
 extern int ufs_write_inode (struct inode *, int);
 extern int ufs_sync_inode (struct inode *);
 extern void ufs_delete_inode (struct inode *);
diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h
index 384dc08d..ac78eba 100644
--- a/include/asm-alpha/barrier.h
+++ b/include/asm-alpha/barrier.h
@@ -24,7 +24,7 @@
 #define smp_mb()	barrier()
 #define smp_rmb()	barrier()
 #define smp_wmb()	barrier()
-#define smp_read_barrier_depends()	barrier()
+#define smp_read_barrier_depends()	do { } while (0)
 #endif
 
 #define set_mb(var, value) \
diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h
index 0982f1d..e691ecf 100644
--- a/include/asm-alpha/param.h
+++ b/include/asm-alpha/param.h
@@ -5,8 +5,12 @@
    hardware ignores reprogramming.  We also need userland buy-in to the 
    change in HZ, since this is visible in the wait4 resources etc.  */
 
+#ifdef __KERNEL__
 #define HZ		CONFIG_HZ
 #define USER_HZ		HZ
+#else
+#define HZ		1024
+#endif
 
 #define EXEC_PAGESIZE	8192
 
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 05ce5fb..3f0c59f6 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -287,17 +287,34 @@
 #define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 #define pgd_offset(mm, address)	((mm)->pgd+pgd_index(address))
 
+/*
+ * The smp_read_barrier_depends() in the following functions are required to
+ * order the load of *dir (the pointer in the top level page table) with any
+ * subsequent load of the returned pmd_t *ret (ret is data dependent on *dir).
+ *
+ * If this ordering is not enforced, the CPU might load an older value of
+ * *ret, which may be uninitialized data. See mm/memory.c:__pte_alloc for
+ * more details.
+ *
+ * Note that we never change the mm->pgd pointer after the task is running, so
+ * pgd_offset does not require such a barrier.
+ */
+
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
 {
-	return (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+	pmd_t *ret = (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+	smp_read_barrier_depends(); /* see above */
+	return ret;
 }
 
 /* Find an entry in the third-level page table.. */
 extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address)
 {
-	return (pte_t *) pmd_page_vaddr(*dir)
+	pte_t *ret = (pte_t *) pmd_page_vaddr(*dir)
 		+ ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1));
+	smp_read_barrier_depends(); /* see above */
+	return ret;
 }
 
 #define pte_offset_map(dir,addr)	pte_offset_kernel((dir),(addr))
diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h
index 9d9f4b5..261e5bc 100644
--- a/include/asm-arm/arch-pxa/pm.h
+++ b/include/asm-arm/arch-pxa/pm.h
@@ -10,7 +10,7 @@
 #include <linux/suspend.h>
 
 struct pxa_cpu_pm_fns {
-	int	save_size;
+	int	save_count;
 	void	(*save)(unsigned long *);
 	void	(*restore)(unsigned long *);
 	int	(*valid)(suspend_state_t state);
diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h
index a758a71..9aa6c2e 100644
--- a/include/asm-arm/arch-pxa/system.h
+++ b/include/asm-arm/arch-pxa/system.h
@@ -22,7 +22,8 @@
 
 static inline void arch_reset(char mode)
 {
-	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+	if (cpu_is_pxa2xx())
+		RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
 
 	if (mode == 's') {
 		/* Jump into ROM at address 0 */
diff --git a/include/asm-blackfin/dpmc.h b/include/asm-blackfin/dpmc.h
index 686cf83..7f34cd3 100644
--- a/include/asm-blackfin/dpmc.h
+++ b/include/asm-blackfin/dpmc.h
@@ -1,7 +1,7 @@
 /*
  * include/asm-blackfin/dpmc.h -  Miscellaneous IOCTL commands for Dynamic Power
  *   			 	Management Controller Driver.
- * Copyright (C) 2004 Analog Device Inc.
+ * Copyright (C) 2004-2008 Analog Device Inc.
  *
  */
 #ifndef _BLACKFIN_DPMC_H_
@@ -65,6 +65,14 @@
 extern unsigned long get_cclk(void);
 extern unsigned long get_sclk(void);
 
+struct bfin_dpmc_platform_data {
+	const unsigned int *tuple_tab;
+	unsigned short tabsize;
+	unsigned short vr_settling_time; /* in us */
+};
+
+#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16))
+
 #endif	/* __KERNEL__ */
 
 #endif	/*_BLACKFIN_DPMC_H_*/
diff --git a/include/asm-blackfin/entry.h b/include/asm-blackfin/entry.h
index 562c6d3..c4f721e 100644
--- a/include/asm-blackfin/entry.h
+++ b/include/asm-blackfin/entry.h
@@ -17,6 +17,11 @@
 #define	PF_DTRACE_OFF	1
 #define	PF_DTRACE_BIT	5
 
+/*
+ * NOTE!  The single-stepping code assumes that all interrupt handlers
+ * start by saving SYSCFG on the stack with their first instruction.
+ */
+
 /* This one is used for exceptions, emulation, and NMI.  It doesn't push
    RETI and doesn't do cli.  */
 #define SAVE_ALL_SYS		save_context_no_interrupts
diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
index f0ab273..26e3c80 100644
--- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
@@ -44,10 +44,15 @@
 #define UART_PUT_CHAR(uart, v)   bfin_write16(((uart)->port.membase + OFFSET_THR), v)
 #define UART_PUT_DLL(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_DLL), v)
 #define UART_PUT_IER(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_IER), v)
+#define UART_SET_IER(uart, v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart, v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_DLH), v)
 #define UART_PUT_LCR(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_LCR), v)
 #define UART_PUT_GCTL(uart, v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL), v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
 # define CONFIG_SERIAL_BFIN_CTSRTS
 
diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
index fbe88de..d016603 100644
--- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
@@ -44,10 +44,15 @@
 #define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
 #define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
 #define UART_PUT_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_SET_IER(uart,v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart,v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
 #define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #ifdef CONFIG_BFIN_UART0_CTSRTS
 # define CONFIG_SERIAL_BFIN_CTSRTS
 # ifndef CONFIG_UART0_CTS_PIN
diff --git a/include/asm-blackfin/mach-bf533/defBF532.h b/include/asm-blackfin/mach-bf533/defBF532.h
index 17e1548..0ab4dd7 100644
--- a/include/asm-blackfin/mach-bf533/defBF532.h
+++ b/include/asm-blackfin/mach-bf533/defBF532.h
@@ -468,6 +468,8 @@
 #define	VLEV_110		0x00B0	/* 		VLEV = 1.10 V (-5% - +10% Accuracy)	*/
 #define	VLEV_115		0x00C0	/* 		VLEV = 1.15 V (-5% - +10% Accuracy)	*/
 #define	VLEV_120		0x00D0	/* 		VLEV = 1.20 V (-5% - +10% Accuracy)	*/
+#define	VLEV_125		0x00E0	/*              VLEV = 1.25 V (-5% - +10% Accuracy)     */
+#define	VLEV_130		0x00F0	/*              VLEV = 1.30 V (-5% - +10% Accuracy)     */
 
 #define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate	*/
 #define	SCKELOW			0x8000	/* Do Not Drive SCKE High During Reset After Hibernate */
diff --git a/include/asm-blackfin/mach-bf533/irq.h b/include/asm-blackfin/mach-bf533/irq.h
index 832e6f6..5aa38e5 100644
--- a/include/asm-blackfin/mach-bf533/irq.h
+++ b/include/asm-blackfin/mach-bf533/irq.h
@@ -66,12 +66,13 @@
 	    DMA8/9 Interrupt	    IVG13	28
 	    DMA10/11 Interrupt	    IVG13	29
 	    Watchdog Timer	    IVG13	30
-            Software Interrupt 1    IVG14       31
-            Software Interrupt 2    --
+
+            Softirq		    IVG14       31
+            System Call    --
                  (lowest priority)  IVG15       32 *
  */
-#define SYS_IRQS		32
-#define NR_PERI_INTS    24
+#define SYS_IRQS	31
+#define NR_PERI_INTS	24
 
 /* The ABSTRACT IRQ definitions */
 /** the first seven of the following are fixed, the rest you change if you need to **/
@@ -96,7 +97,7 @@
 #define	IRQ_SPORT0_TX		17	/*DMA2 Interrupt (SPORT0 TX) */
 #define	IRQ_SPORT1_RX		18	/*DMA3 Interrupt (SPORT1 RX) */
 #define	IRQ_SPORT1_TX		19	/*DMA4 Interrupt (SPORT1 TX) */
-#define IRQ_SPI			20	/*DMA5 Interrupt (SPI) */
+#define 	IRQ_SPI			20	/*DMA5 Interrupt (SPI) */
 #define	IRQ_UART_RX		21	/*DMA6 Interrupt (UART RX) */
 #define	IRQ_UART_TX		22	/*DMA7 Interrupt (UART TX) */
 #define	IRQ_TMR0		23	/*Timer 0 */
@@ -108,9 +109,6 @@
 #define	IRQ_MEM_DMA1		29	/*DMA10/11 Interrupt (Memory DMA Stream 1) */
 #define	IRQ_WATCH	   	30	/*Watch Dog Timer */
 
-#define	IRQ_SW_INT1		31	/*Software Int 1 */
-#define	IRQ_SW_INT2		32	/*Software Int 2 (reserved for SYSCALL) */
-
 #define IRQ_PF0			33
 #define IRQ_PF1			34
 #define IRQ_PF2			35
diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
index fd100a4..f79d1a0 100644
--- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
@@ -44,10 +44,15 @@
 #define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
 #define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
 #define UART_PUT_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_SET_IER(uart,v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart,v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
 #define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
 # define CONFIG_SERIAL_BFIN_CTSRTS
 
diff --git a/include/asm-blackfin/mach-bf537/irq.h b/include/asm-blackfin/mach-bf537/irq.h
index be6f2ff..2e68a8a 100644
--- a/include/asm-blackfin/mach-bf537/irq.h
+++ b/include/asm-blackfin/mach-bf537/irq.h
@@ -34,24 +34,23 @@
 
 /*
  * Interrupt source definitions
-             Event Source    Core Event Name
-Core        Emulation               **
- Events         (highest priority)  EMU         0
-            Reset                   RST         1
-            NMI                     NMI         2
-            Exception               EVX         3
-            Reserved                --          4
-            Hardware Error          IVHW        5
-            Core Timer              IVTMR       6 *
-
-.....
-
-            Software Interrupt 1    IVG14       31
-            Software Interrupt 2    --
-                 (lowest priority)  IVG15       32 *
+ *            Event Source    Core Event Name
+ * Core       Emulation               **
+ * Events         (highest priority)  EMU         0
+ *            Reset                   RST         1
+ *            NMI                     NMI         2
+ *            Exception               EVX         3
+ *            Reserved                --          4
+ *            Hardware Error          IVHW        5
+ *            Core Timer              IVTMR       6
+ *  .....
+ *
+ *            Softirq		      IVG14
+ *            System Call    --
+ *               (lowest priority)    IVG15
  */
 
-#define SYS_IRQS        41
+#define SYS_IRQS        39
 #define NR_PERI_INTS    32
 
 /* The ABSTRACT IRQ definitions */
@@ -95,10 +94,8 @@
 #define IRQ_PORTG_INTB      35	/* PF Port G (PF15:0) Interrupt B */
 #define IRQ_MEM_DMA0        36	/*(Memory DMA Stream 0) */
 #define IRQ_MEM_DMA1        37	/*(Memory DMA Stream 1) */
-#define IRQ_PROG_INTB	    38	/* PF Ports F (PF15:0) Interrupt B */
+#define IRQ_PROG_INTB	      38	/* PF Ports F (PF15:0) Interrupt B */
 #define IRQ_WATCH           38	/*Watch Dog Timer */
-#define IRQ_SW_INT1         40	/*Software Int 1 */
-#define IRQ_SW_INT2         41	/*Software Int 2 (reserved for SYSCALL) */
 
 #define IRQ_PPI_ERROR       42	/*PPI Error Interrupt */
 #define IRQ_CAN_ERROR       43	/*CAN Error Interrupt */
diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
index 6547027..5eb46a7 100644
--- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
@@ -54,6 +54,9 @@
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 #define UART_PUT_MCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_MCR),v)
 
+#define UART_SET_DLAB(uart)     /* MMRs not muxed on BF54x */
+#define UART_CLEAR_DLAB(uart)   /* MMRs not muxed on BF54x */
+
 #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
 # define CONFIG_SERIAL_BFIN_CTSRTS
 
diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h
index 08f90c2..e022e89 100644
--- a/include/asm-blackfin/mach-bf548/defBF54x_base.h
+++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h
@@ -2329,6 +2329,26 @@
 #define                    KPADWE  0x1000     /* Keypad Wake-Up Enable */
 #define                     ROTWE  0x2000     /* Rotary Wake-Up Enable */
 
+#define	FREQ_333		0x0001	/* Switching Frequency Is 333 kHz */
+#define	FREQ_667		0x0002	/* Switching Frequency Is 667 kHz */
+#define	FREQ_1000		0x0003	/* Switching Frequency Is 1 MHz */
+
+#define	GAIN_5			0x0000	/* GAIN = 5*/
+#define	GAIN_10			0x0004	/* GAIN = 1*/
+#define	GAIN_20			0x0008	/* GAIN = 2*/
+#define	GAIN_50			0x000C	/* GAIN = 5*/
+
+#define	VLEV_085 		0x0060	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define	VLEV_090		0x0070	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
+#define	VLEV_095		0x0080	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
+#define	VLEV_100		0x0090	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
+#define	VLEV_105		0x00A0	/* VLEV = 1.05 V (-5% - +10% Accuracy) */
+#define	VLEV_110		0x00B0	/* VLEV = 1.10 V (-5% - +10% Accuracy) */
+#define	VLEV_115		0x00C0	/* VLEV = 1.15 V (-5% - +10% Accuracy) */
+#define	VLEV_120		0x00D0	/* VLEV = 1.20 V (-5% - +10% Accuracy) */
+#define	VLEV_125		0x00E0	/* VLEV = 1.25 V (-5% - +10% Accuracy) */
+#define	VLEV_130		0x00F0	/* VLEV = 1.30 V (-5% - +10% Accuracy) */
+
 /* Bit masks for NFC_CTL */
 
 #define                    WR_DLY  0xf        /* Write Strobe Delay */
diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
index 8a4e66d..7a96287 100644
--- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
+++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
@@ -44,10 +44,15 @@
 #define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
 #define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
 #define UART_PUT_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_SET_IER(uart,v)    UART_PUT_IER(uart, UART_GET_IER(uart) | (v))
+#define UART_CLEAR_IER(uart,v)  UART_PUT_IER(uart, UART_GET_IER(uart) & ~(v))
 #define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
 #define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 
+#define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
+#define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
+
 #ifdef CONFIG_BFIN_UART0_CTSRTS
 # define CONFIG_SERIAL_BFIN_CTSRTS
 # ifndef CONFIG_UART0_CTS_PIN
diff --git a/include/asm-blackfin/mach-bf561/defBF561.h b/include/asm-blackfin/mach-bf561/defBF561.h
index 366c9b9..1ab50e9 100644
--- a/include/asm-blackfin/mach-bf561/defBF561.h
+++ b/include/asm-blackfin/mach-bf561/defBF561.h
@@ -868,6 +868,34 @@
 #define CHIPID_FAMILY          0x0FFFF000
 #define CHIPID_MANUFACTURE     0x00000FFE
 
+/* VR_CTL Masks																	*/
+#define	FREQ			0x0003	/* Switching Oscillator Frequency For Regulator	*/
+#define	HIBERNATE		0x0000	/* Powerdown/Bypass On-Board Regulation	*/
+#define	FREQ_333		0x0001	/* Switching Frequency Is 333 kHz */
+#define	FREQ_667		0x0002	/* Switching Frequency Is 667 kHz */
+#define	FREQ_1000		0x0003	/* Switching Frequency Is 1 MHz */
+
+#define	GAIN			0x000C	/* Voltage Level Gain	*/
+#define	GAIN_5			0x0000	/* GAIN = 5*/
+#define	GAIN_10			0x0004	/* GAIN = 1*/
+#define	GAIN_20			0x0008	/* GAIN = 2*/
+#define	GAIN_50			0x000C	/* GAIN = 5*/
+
+#define	VLEV			0x00F0	/* Internal Voltage Level */
+#define	VLEV_085 		0x0060	/* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define	VLEV_090		0x0070	/* VLEV = 0.90 V (-5% - +10% Accuracy) */
+#define	VLEV_095		0x0080	/* VLEV = 0.95 V (-5% - +10% Accuracy) */
+#define	VLEV_100		0x0090	/* VLEV = 1.00 V (-5% - +10% Accuracy) */
+#define	VLEV_105		0x00A0	/* VLEV = 1.05 V (-5% - +10% Accuracy) */
+#define	VLEV_110		0x00B0	/* VLEV = 1.10 V (-5% - +10% Accuracy) */
+#define	VLEV_115		0x00C0	/* VLEV = 1.15 V (-5% - +10% Accuracy) */
+#define	VLEV_120		0x00D0	/* VLEV = 1.20 V (-5% - +10% Accuracy) */
+#define	VLEV_125		0x00E0	/* VLEV = 1.25 V (-5% - +10% Accuracy) */
+#define	VLEV_130		0x00F0	/* VLEV = 1.30 V (-5% - +10% Accuracy) */
+
+#define	WAKE			0x0100	/* Enable RTC/Reset Wakeup From Hibernate */
+#define	SCKELOW			0x8000	/* Do Not Drive SCKE High During Reset After Hibernate */
+
 /* PLL_DIV Masks */
 #define SCLK_DIV(x)  (x)	/* SCLK = VCO / x */
 
diff --git a/include/asm-blackfin/mach-bf561/irq.h b/include/asm-blackfin/mach-bf561/irq.h
index 83f0383..6698389 100644
--- a/include/asm-blackfin/mach-bf561/irq.h
+++ b/include/asm-blackfin/mach-bf561/irq.h
@@ -118,12 +118,13 @@
 	    Supplemental interrupt 0		IVG7	    69
 	    supplemental interrupt 1		IVG7	    70
 
-            Software Interrupt 1		IVG14       71
-            Software Interrupt 2		IVG15       72 *
-						(lowest priority)
+            Softirq		    		IVG14
+            System Call    --
+                 (lowest priority)  		IVG15
+
  **********************************************************************/
 
-#define SYS_IRQS		72
+#define SYS_IRQS		71
 #define NR_PERI_INTS		64
 
 /*
@@ -237,9 +238,7 @@
 #define IRQ_RESERVED_2		(IVG_BASE + 61)	/* Reserved interrupt       */
 #define IRQ_SUPPLE_0		(IVG_BASE + 62)	/* Supplemental interrupt 0 */
 #define IRQ_SUPPLE_1		(IVG_BASE + 63)	/* supplemental interrupt 1 */
-#define	IRQ_SW_INT1		71	/* Software Interrupt 1     */
-#define	IRQ_SW_INT2		72	/* Software Interrupt 2     */
-						/* reserved for SYSCALL */
+
 #define IRQ_PF0			73
 #define IRQ_PF1			74
 #define IRQ_PF2			75
diff --git a/include/asm-blackfin/mach-common/context.S b/include/asm-blackfin/mach-common/context.S
index fd0ebe1..c0e630e 100644
--- a/include/asm-blackfin/mach-common/context.S
+++ b/include/asm-blackfin/mach-common/context.S
@@ -28,6 +28,11 @@
  */
 
 /*
+ * NOTE!  The single-stepping code assumes that all interrupt handlers
+ * start by saving SYSCFG on the stack with their first instruction.
+ */
+
+/*
  * Code to save processor context.
  *  We even save the register which are preserved by a function call
  *	 - r4, r5, r6, r7, p3, p4, p5
diff --git a/include/asm-blackfin/time.h b/include/asm-blackfin/time.h
index 6e5859b..ddc43ce 100644
--- a/include/asm-blackfin/time.h
+++ b/include/asm-blackfin/time.h
@@ -24,6 +24,8 @@
 
 #ifndef CONFIG_CPU_FREQ
 #define TIME_SCALE 1
+#define __bfin_cycles_off (0)
+#define __bfin_cycles_mod (0)
 #else
 /*
  * Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 .
@@ -31,6 +33,8 @@
  * adjust the Core Timer Presale Register. This way we don't lose time.
  */
 #define TIME_SCALE 4
+extern unsigned long long __bfin_cycles_off;
+extern unsigned int __bfin_cycles_mod;
 #endif
 
 #endif
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
index cb307f8..d3a12a9 100644
--- a/include/asm-frv/system.h
+++ b/include/asm-frv/system.h
@@ -179,7 +179,7 @@
 #define mb()			asm volatile ("membar" : : :"memory")
 #define rmb()			asm volatile ("membar" : : :"memory")
 #define wmb()			asm volatile ("membar" : : :"memory")
-#define read_barrier_depends()	barrier()
+#define read_barrier_depends()	do { } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()			mb()
diff --git a/include/asm-h8300/param.h b/include/asm-h8300/param.h
index 04f64f1..1c72fb8 100644
--- a/include/asm-h8300/param.h
+++ b/include/asm-h8300/param.h
@@ -1,14 +1,12 @@
 #ifndef _H8300_PARAM_H
 #define _H8300_PARAM_H
 
-
-#ifndef HZ
-#define HZ CONFIG_HZ
-#endif
-
 #ifdef __KERNEL__
+#define HZ		CONFIG_HZ
 #define	USER_HZ		HZ
 #define	CLOCKS_PER_SEC	(USER_HZ)
+#else
+#define HZ		100
 #endif
 
 #define EXEC_PAGESIZE	4096
diff --git a/include/asm-m68k/machw.h b/include/asm-m68k/machw.h
index d2e0e25..3562499 100644
--- a/include/asm-m68k/machw.h
+++ b/include/asm-m68k/machw.h
@@ -66,36 +66,6 @@
 # define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS))
 #endif
 
-/* hardware stuff */
-
-#define MACHW_DECLARE(name)	unsigned name : 1
-#define MACHW_SET(name)		(mac_hw_present.name = 1)
-#define MACHW_PRESENT(name)	(mac_hw_present.name)
-
-struct mac_hw_present {
-  /* video hardware */
-  /* sound hardware */
-  /* disk storage interfaces */
-  MACHW_DECLARE(MAC_SCSI_80);     /* Directly mapped NCR5380 */
-  MACHW_DECLARE(MAC_SCSI_96);     /* 53c9[46] */
-  MACHW_DECLARE(MAC_SCSI_96_2);   /* 2nd 53c9[46] Q900 and Q950 */
-  MACHW_DECLARE(IDE);             /* IDE Interface */
-  /* other I/O hardware */
-  MACHW_DECLARE(SCC);             /* Serial Communications Contr. */
-  /* DMA */
-  MACHW_DECLARE(SCSI_DMA);        /* DMA for the NCR5380 */
-  /* real time clocks */
-  MACHW_DECLARE(RTC_CLK);         /* clock chip */
-  /* supporting hardware */
-  MACHW_DECLARE(VIA1);            /* Versatile Interface Ad. 1 */
-  MACHW_DECLARE(VIA2);            /* Versatile Interface Ad. 2 */
-  MACHW_DECLARE(RBV);             /* Versatile Interface Ad. 2+ */
-  /* NUBUS */
-  MACHW_DECLARE(NUBUS);           /* NUBUS */
-};
-
-extern struct mac_hw_present mac_hw_present;
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* linux/machw.h */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index c2bd126..6427247 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -558,11 +558,13 @@
 	__clear_bit(nr, addr);
 }
 
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+
 /*
  * Return the bit position (0..63) of the most significant 1 bit in a word
  * Returns -1 if no 1 bit exists
  */
-static inline int __ilog2(unsigned long x)
+static inline unsigned long __fls(unsigned long x)
 {
 	int lz;
 
@@ -591,13 +593,6 @@
 	return 63 - lz;
 }
 
-static inline unsigned long __fls(unsigned long x)
-{
-	return __ilog2(x);
-}
-
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-
 /*
  * __ffs - find first bit in word.
  * @word: The word to search
@@ -607,7 +602,7 @@
  */
 static inline unsigned long __ffs(unsigned long word)
 {
-	return __ilog2(word & -word);
+	return __fls(word & -word);
 }
 
 /*
@@ -654,6 +649,7 @@
 #else
 
 #include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/__fls.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/fls.h>
 #include <asm-generic/bitops/fls64.h>
diff --git a/include/asm-mips/compiler.h b/include/asm-mips/compiler.h
index aa6b876..71f5c5c 100644
--- a/include/asm-mips/compiler.h
+++ b/include/asm-mips/compiler.h
@@ -9,10 +9,10 @@
 #define _ASM_COMPILER_H
 
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-#define GCC_IMM_ASM "n"
+#define GCC_IMM_ASM() "n"
 #define GCC_REG_ACCUM "$0"
 #else
-#define GCC_IMM_ASM "rn"
+#define GCC_IMM_ASM() "rn"
 #define GCC_REG_ACCUM "accum"
 #endif
 
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
index a0555516..363a14e 100644
--- a/include/asm-mips/mach-au1x00/au1000.h
+++ b/include/asm-mips/mach-au1x00/au1000.h
@@ -40,8 +40,8 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 
 /* cpu pipeline flush */
 void static inline au_sync(void)
@@ -63,32 +63,32 @@
 
 void static inline au_writeb(u8 val, unsigned long reg)
 {
-	*(volatile u8 *)(reg) = val;
+	*(volatile u8 *)reg = val;
 }
 
 void static inline au_writew(u16 val, unsigned long reg)
 {
-	*(volatile u16 *)(reg) = val;
+	*(volatile u16 *)reg = val;
 }
 
 void static inline au_writel(u32 val, unsigned long reg)
 {
-	*(volatile u32 *)(reg) = val;
+	*(volatile u32 *)reg = val;
 }
 
 static inline u8 au_readb(unsigned long reg)
 {
-	return (*(volatile u8 *)reg);
+	return *(volatile u8 *)reg;
 }
 
 static inline u16 au_readw(unsigned long reg)
 {
-	return (*(volatile u16 *)reg);
+	return *(volatile u16 *)reg;
 }
 
 static inline u32 au_readl(unsigned long reg)
 {
-	return (*(volatile u32 *)reg);
+	return *(volatile u32 *)reg;
 }
 
 
@@ -117,76 +117,77 @@
 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
 
 /*
- * SDRAM Register Offsets
+ * SDRAM register offsets
  */
-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
-#define MEM_SDMODE0		(0x0000)
-#define MEM_SDMODE1		(0x0004)
-#define MEM_SDMODE2		(0x0008)
-#define MEM_SDADDR0		(0x000C)
-#define MEM_SDADDR1		(0x0010)
-#define MEM_SDADDR2		(0x0014)
-#define MEM_SDREFCFG	(0x0018)
-#define MEM_SDPRECMD	(0x001C)
-#define MEM_SDAUTOREF	(0x0020)
-#define MEM_SDWRMD0		(0x0024)
-#define MEM_SDWRMD1		(0x0028)
-#define MEM_SDWRMD2		(0x002C)
-#define MEM_SDSLEEP		(0x0030)
-#define MEM_SDSMCKE		(0x0034)
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
+    defined(CONFIG_SOC_AU1100)
+#define MEM_SDMODE0		0x0000
+#define MEM_SDMODE1		0x0004
+#define MEM_SDMODE2		0x0008
+#define MEM_SDADDR0		0x000C
+#define MEM_SDADDR1		0x0010
+#define MEM_SDADDR2		0x0014
+#define MEM_SDREFCFG		0x0018
+#define MEM_SDPRECMD		0x001C
+#define MEM_SDAUTOREF		0x0020
+#define MEM_SDWRMD0		0x0024
+#define MEM_SDWRMD1		0x0028
+#define MEM_SDWRMD2		0x002C
+#define MEM_SDSLEEP		0x0030
+#define MEM_SDSMCKE		0x0034
 
 /*
  * MEM_SDMODE register content definitions
  */
-#define MEM_SDMODE_F		(1<<22)
-#define MEM_SDMODE_SR		(1<<21)
-#define MEM_SDMODE_BS		(1<<20)
-#define MEM_SDMODE_RS		(3<<18)
-#define MEM_SDMODE_CS		(7<<15)
-#define MEM_SDMODE_TRAS		(15<<11)
-#define MEM_SDMODE_TMRD		(3<<9)
-#define MEM_SDMODE_TWR		(3<<7)
-#define MEM_SDMODE_TRP		(3<<5)
-#define MEM_SDMODE_TRCD		(3<<3)
-#define MEM_SDMODE_TCL		(7<<0)
+#define MEM_SDMODE_F		(1 << 22)
+#define MEM_SDMODE_SR		(1 << 21)
+#define MEM_SDMODE_BS		(1 << 20)
+#define MEM_SDMODE_RS		(3 << 18)
+#define MEM_SDMODE_CS		(7 << 15)
+#define MEM_SDMODE_TRAS 	(15 << 11)
+#define MEM_SDMODE_TMRD 	(3 << 9)
+#define MEM_SDMODE_TWR		(3 << 7)
+#define MEM_SDMODE_TRP		(3 << 5)
+#define MEM_SDMODE_TRCD 	(3 << 3)
+#define MEM_SDMODE_TCL		(7 << 0)
 
-#define MEM_SDMODE_BS_2Bank	(0<<20)
-#define MEM_SDMODE_BS_4Bank	(1<<20)
-#define MEM_SDMODE_RS_11Row	(0<<18)
-#define MEM_SDMODE_RS_12Row	(1<<18)
-#define MEM_SDMODE_RS_13Row	(2<<18)
-#define MEM_SDMODE_RS_N(N)	((N)<<18)
-#define MEM_SDMODE_CS_7Col	(0<<15)
-#define MEM_SDMODE_CS_8Col	(1<<15)
-#define MEM_SDMODE_CS_9Col	(2<<15)
-#define MEM_SDMODE_CS_10Col	(3<<15)
-#define MEM_SDMODE_CS_11Col	(4<<15)
-#define MEM_SDMODE_CS_N(N)		((N)<<15)
-#define MEM_SDMODE_TRAS_N(N)	((N)<<11)
-#define MEM_SDMODE_TMRD_N(N)	((N)<<9)
-#define MEM_SDMODE_TWR_N(N)		((N)<<7)
-#define MEM_SDMODE_TRP_N(N)		((N)<<5)
-#define MEM_SDMODE_TRCD_N(N)	((N)<<3)
-#define MEM_SDMODE_TCL_N(N)		((N)<<0)
+#define MEM_SDMODE_BS_2Bank	(0 << 20)
+#define MEM_SDMODE_BS_4Bank	(1 << 20)
+#define MEM_SDMODE_RS_11Row	(0 << 18)
+#define MEM_SDMODE_RS_12Row	(1 << 18)
+#define MEM_SDMODE_RS_13Row	(2 << 18)
+#define MEM_SDMODE_RS_N(N)	((N) << 18)
+#define MEM_SDMODE_CS_7Col	(0 << 15)
+#define MEM_SDMODE_CS_8Col	(1 << 15)
+#define MEM_SDMODE_CS_9Col	(2 << 15)
+#define MEM_SDMODE_CS_10Col	(3 << 15)
+#define MEM_SDMODE_CS_11Col	(4 << 15)
+#define MEM_SDMODE_CS_N(N)	((N) << 15)
+#define MEM_SDMODE_TRAS_N(N)	((N) << 11)
+#define MEM_SDMODE_TMRD_N(N)	((N) << 9)
+#define MEM_SDMODE_TWR_N(N)	((N) << 7)
+#define MEM_SDMODE_TRP_N(N)	((N) << 5)
+#define MEM_SDMODE_TRCD_N(N)	((N) << 3)
+#define MEM_SDMODE_TCL_N(N)	((N) << 0)
 
 /*
  * MEM_SDADDR register contents definitions
  */
-#define MEM_SDADDR_E			(1<<20)
-#define MEM_SDADDR_CSBA			(0x03FF<<10)
-#define MEM_SDADDR_CSMASK		(0x03FF<<0)
-#define MEM_SDADDR_CSBA_N(N)	((N)&(0x03FF<<22)>>12)
-#define MEM_SDADDR_CSMASK_N(N)	((N)&(0x03FF<<22)>>22)
+#define MEM_SDADDR_E		(1 << 20)
+#define MEM_SDADDR_CSBA 	(0x03FF << 10)
+#define MEM_SDADDR_CSMASK	(0x03FF << 0)
+#define MEM_SDADDR_CSBA_N(N)	((N) & (0x03FF << 22) >> 12)
+#define MEM_SDADDR_CSMASK_N(N)	((N)&(0x03FF << 22) >> 22)
 
 /*
  * MEM_SDREFCFG register content definitions
  */
-#define MEM_SDREFCFG_TRC		(15<<28)
-#define MEM_SDREFCFG_TRPM		(3<<26)
-#define MEM_SDREFCFG_E			(1<<25)
-#define MEM_SDREFCFG_RE			(0x1ffffff<<0)
-#define MEM_SDREFCFG_TRC_N(N)	((N)<<MEM_SDREFCFG_TRC)
-#define MEM_SDREFCFG_TRPM_N(N)	((N)<<MEM_SDREFCFG_TRPM)
+#define MEM_SDREFCFG_TRC	(15 << 28)
+#define MEM_SDREFCFG_TRPM	(3 << 26)
+#define MEM_SDREFCFG_E		(1 << 25)
+#define MEM_SDREFCFG_RE 	(0x1ffffff << 0)
+#define MEM_SDREFCFG_TRC_N(N)	((N) << MEM_SDREFCFG_TRC)
+#define MEM_SDREFCFG_TRPM_N(N)	((N) << MEM_SDREFCFG_TRPM)
 #define MEM_SDREFCFG_REF_N(N)	(N)
 #endif
 
@@ -199,25 +200,25 @@
 /***********************************************************************/
 
 #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
-#define MEM_SDMODE0		(0x0800)
-#define MEM_SDMODE1		(0x0808)
-#define MEM_SDMODE2		(0x0810)
-#define MEM_SDADDR0		(0x0820)
-#define MEM_SDADDR1		(0x0828)
-#define MEM_SDADDR2		(0x0830)
-#define MEM_SDCONFIGA	(0x0840)
-#define MEM_SDCONFIGB	(0x0848)
-#define MEM_SDSTAT		(0x0850)
-#define MEM_SDERRADDR	(0x0858)
-#define MEM_SDSTRIDE0	(0x0860)
-#define MEM_SDSTRIDE1	(0x0868)
-#define MEM_SDSTRIDE2	(0x0870)
-#define MEM_SDWRMD0		(0x0880)
-#define MEM_SDWRMD1		(0x0888)
-#define MEM_SDWRMD2		(0x0890)
-#define MEM_SDPRECMD	(0x08C0)
-#define MEM_SDAUTOREF	(0x08C8)
-#define MEM_SDSREF		(0x08D0)
+#define MEM_SDMODE0		0x0800
+#define MEM_SDMODE1		0x0808
+#define MEM_SDMODE2		0x0810
+#define MEM_SDADDR0		0x0820
+#define MEM_SDADDR1		0x0828
+#define MEM_SDADDR2		0x0830
+#define MEM_SDCONFIGA		0x0840
+#define MEM_SDCONFIGB		0x0848
+#define MEM_SDSTAT		0x0850
+#define MEM_SDERRADDR		0x0858
+#define MEM_SDSTRIDE0		0x0860
+#define MEM_SDSTRIDE1		0x0868
+#define MEM_SDSTRIDE2		0x0870
+#define MEM_SDWRMD0		0x0880
+#define MEM_SDWRMD1		0x0888
+#define MEM_SDWRMD2		0x0890
+#define MEM_SDPRECMD		0x08C0
+#define MEM_SDAUTOREF		0x08C8
+#define MEM_SDSREF		0x08D0
 #define MEM_SDSLEEP		MEM_SDSREF
 
 #endif
@@ -256,9 +257,9 @@
 #define	SSI0_PHYS_ADDR		0x11600000
 #define	SSI1_PHYS_ADDR		0x11680000
 #define	SYS_PHYS_ADDR		0x11900000
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
 #endif
 
 /********************************************************************/
@@ -290,13 +291,13 @@
 #define	UART3_PHYS_ADDR		0x11400000
 #define GPIO2_PHYS_ADDR		0x11700000
 #define	SYS_PHYS_ADDR		0x11900000
-#define PCI_MEM_PHYS_ADDR     0x400000000ULL
-#define PCI_IO_PHYS_ADDR      0x500000000ULL
-#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
-#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCI_MEM_PHYS_ADDR	0x400000000ULL
+#define PCI_IO_PHYS_ADDR	0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR	0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR	0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
 #endif
 
 /********************************************************************/
@@ -333,9 +334,9 @@
 #define GPIO2_PHYS_ADDR		0x11700000
 #define	SYS_PHYS_ADDR		0x11900000
 #define LCD_PHYS_ADDR		0x15000000
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
 #endif
 
 /***********************************************************************/
@@ -360,17 +361,17 @@
 #define	SYS_PHYS_ADDR		0x11900000
 #define	DDMA_PHYS_ADDR		0x14002000
 #define PE_PHYS_ADDR		0x14008000
-#define PSC0_PHYS_ADDR	 	0x11A00000
-#define PSC1_PHYS_ADDR	 	0x11B00000
-#define PSC2_PHYS_ADDR	 	0x10A00000
-#define PSC3_PHYS_ADDR	 	0x10B00000
-#define PCI_MEM_PHYS_ADDR     0x400000000ULL
-#define PCI_IO_PHYS_ADDR      0x500000000ULL
-#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
-#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PSC0_PHYS_ADDR		0x11A00000
+#define PSC1_PHYS_ADDR		0x11B00000
+#define PSC2_PHYS_ADDR		0x10A00000
+#define PSC3_PHYS_ADDR		0x10B00000
+#define PCI_MEM_PHYS_ADDR	0x400000000ULL
+#define PCI_IO_PHYS_ADDR	0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR	0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR	0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
 #endif
 
 /***********************************************************************/
@@ -397,122 +398,121 @@
 #define SWCNT_PHYS_ADDR		0x1110010C
 #define MAEFE_PHYS_ADDR		0x14012000
 #define MAEBE_PHYS_ADDR		0x14010000
-#define PCMCIA_IO_PHYS_ADDR   0xF00000000ULL
-#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
-#define PCMCIA_MEM_PHYS_ADDR  0xF80000000ULL
+#define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
 #endif
 
-
 /* Static Bus Controller */
-#define MEM_STCFG0                 0xB4001000
-#define MEM_STTIME0                0xB4001004
-#define MEM_STADDR0                0xB4001008
+#define MEM_STCFG0		0xB4001000
+#define MEM_STTIME0		0xB4001004
+#define MEM_STADDR0		0xB4001008
 
-#define MEM_STCFG1                 0xB4001010
-#define MEM_STTIME1                0xB4001014
-#define MEM_STADDR1                0xB4001018
+#define MEM_STCFG1		0xB4001010
+#define MEM_STTIME1		0xB4001014
+#define MEM_STADDR1		0xB4001018
 
-#define MEM_STCFG2                 0xB4001020
-#define MEM_STTIME2                0xB4001024
-#define MEM_STADDR2                0xB4001028
+#define MEM_STCFG2		0xB4001020
+#define MEM_STTIME2		0xB4001024
+#define MEM_STADDR2		0xB4001028
 
-#define MEM_STCFG3                 0xB4001030
-#define MEM_STTIME3                0xB4001034
-#define MEM_STADDR3                0xB4001038
+#define MEM_STCFG3		0xB4001030
+#define MEM_STTIME3		0xB4001034
+#define MEM_STADDR3		0xB4001038
 
 #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
-#define MEM_STNDCTL                0xB4001100
-#define MEM_STSTAT                 0xB4001104
+#define MEM_STNDCTL		0xB4001100
+#define MEM_STSTAT		0xB4001104
 
-#define MEM_STNAND_CMD                  (0x0)
-#define MEM_STNAND_ADDR                 (0x4)
-#define MEM_STNAND_DATA                (0x20)
+#define MEM_STNAND_CMD		0x0
+#define MEM_STNAND_ADDR 	0x4
+#define MEM_STNAND_DATA 	0x20
 #endif
 
 /* Interrupt Controller 0 */
-#define IC0_CFG0RD                 0xB0400040
-#define IC0_CFG0SET                0xB0400040
-#define IC0_CFG0CLR                0xB0400044
+#define IC0_CFG0RD		0xB0400040
+#define IC0_CFG0SET		0xB0400040
+#define IC0_CFG0CLR		0xB0400044
 
-#define IC0_CFG1RD                 0xB0400048
-#define IC0_CFG1SET                0xB0400048
-#define IC0_CFG1CLR                0xB040004C
+#define IC0_CFG1RD		0xB0400048
+#define IC0_CFG1SET		0xB0400048
+#define IC0_CFG1CLR		0xB040004C
 
-#define IC0_CFG2RD                 0xB0400050
-#define IC0_CFG2SET                0xB0400050
-#define IC0_CFG2CLR                0xB0400054
+#define IC0_CFG2RD		0xB0400050
+#define IC0_CFG2SET		0xB0400050
+#define IC0_CFG2CLR		0xB0400054
 
-#define IC0_REQ0INT                0xB0400054
-#define IC0_SRCRD                  0xB0400058
-#define IC0_SRCSET                 0xB0400058
-#define IC0_SRCCLR                 0xB040005C
-#define IC0_REQ1INT                0xB040005C
+#define IC0_REQ0INT		0xB0400054
+#define IC0_SRCRD		0xB0400058
+#define IC0_SRCSET		0xB0400058
+#define IC0_SRCCLR		0xB040005C
+#define IC0_REQ1INT		0xB040005C
 
-#define IC0_ASSIGNRD               0xB0400060
-#define IC0_ASSIGNSET              0xB0400060
-#define IC0_ASSIGNCLR              0xB0400064
+#define IC0_ASSIGNRD		0xB0400060
+#define IC0_ASSIGNSET		0xB0400060
+#define IC0_ASSIGNCLR		0xB0400064
 
-#define IC0_WAKERD                 0xB0400068
-#define IC0_WAKESET                0xB0400068
-#define IC0_WAKECLR                0xB040006C
+#define IC0_WAKERD		0xB0400068
+#define IC0_WAKESET		0xB0400068
+#define IC0_WAKECLR		0xB040006C
 
-#define IC0_MASKRD                 0xB0400070
-#define IC0_MASKSET                0xB0400070
-#define IC0_MASKCLR                0xB0400074
+#define IC0_MASKRD		0xB0400070
+#define IC0_MASKSET		0xB0400070
+#define IC0_MASKCLR		0xB0400074
 
-#define IC0_RISINGRD               0xB0400078
-#define IC0_RISINGCLR              0xB0400078
-#define IC0_FALLINGRD              0xB040007C
-#define IC0_FALLINGCLR             0xB040007C
+#define IC0_RISINGRD		0xB0400078
+#define IC0_RISINGCLR		0xB0400078
+#define IC0_FALLINGRD		0xB040007C
+#define IC0_FALLINGCLR		0xB040007C
 
-#define IC0_TESTBIT                0xB0400080
+#define IC0_TESTBIT		0xB0400080
 
 /* Interrupt Controller 1 */
-#define IC1_CFG0RD                 0xB1800040
-#define IC1_CFG0SET                0xB1800040
-#define IC1_CFG0CLR                0xB1800044
+#define IC1_CFG0RD		0xB1800040
+#define IC1_CFG0SET		0xB1800040
+#define IC1_CFG0CLR		0xB1800044
 
-#define IC1_CFG1RD                 0xB1800048
-#define IC1_CFG1SET                0xB1800048
-#define IC1_CFG1CLR                0xB180004C
+#define IC1_CFG1RD		0xB1800048
+#define IC1_CFG1SET		0xB1800048
+#define IC1_CFG1CLR		0xB180004C
 
-#define IC1_CFG2RD                 0xB1800050
-#define IC1_CFG2SET                0xB1800050
-#define IC1_CFG2CLR                0xB1800054
+#define IC1_CFG2RD		0xB1800050
+#define IC1_CFG2SET		0xB1800050
+#define IC1_CFG2CLR		0xB1800054
 
-#define IC1_REQ0INT                0xB1800054
-#define IC1_SRCRD                  0xB1800058
-#define IC1_SRCSET                 0xB1800058
-#define IC1_SRCCLR                 0xB180005C
-#define IC1_REQ1INT                0xB180005C
+#define IC1_REQ0INT		0xB1800054
+#define IC1_SRCRD		0xB1800058
+#define IC1_SRCSET		0xB1800058
+#define IC1_SRCCLR		0xB180005C
+#define IC1_REQ1INT		0xB180005C
 
-#define IC1_ASSIGNRD               0xB1800060
-#define IC1_ASSIGNSET              0xB1800060
-#define IC1_ASSIGNCLR              0xB1800064
+#define IC1_ASSIGNRD            0xB1800060
+#define IC1_ASSIGNSET           0xB1800060
+#define IC1_ASSIGNCLR           0xB1800064
 
-#define IC1_WAKERD                 0xB1800068
-#define IC1_WAKESET                0xB1800068
-#define IC1_WAKECLR                0xB180006C
+#define IC1_WAKERD		0xB1800068
+#define IC1_WAKESET		0xB1800068
+#define IC1_WAKECLR		0xB180006C
 
-#define IC1_MASKRD                 0xB1800070
-#define IC1_MASKSET                0xB1800070
-#define IC1_MASKCLR                0xB1800074
+#define IC1_MASKRD		0xB1800070
+#define IC1_MASKSET		0xB1800070
+#define IC1_MASKCLR		0xB1800074
 
-#define IC1_RISINGRD               0xB1800078
-#define IC1_RISINGCLR              0xB1800078
-#define IC1_FALLINGRD              0xB180007C
-#define IC1_FALLINGCLR             0xB180007C
+#define IC1_RISINGRD		0xB1800078
+#define IC1_RISINGCLR		0xB1800078
+#define IC1_FALLINGRD		0xB180007C
+#define IC1_FALLINGCLR		0xB180007C
 
-#define IC1_TESTBIT                0xB1800080
+#define IC1_TESTBIT		0xB1800080
 
 /* Interrupt Configuration Modes */
-#define INTC_INT_DISABLED                0
-#define INTC_INT_RISE_EDGE             0x1
-#define INTC_INT_FALL_EDGE             0x2
-#define INTC_INT_RISE_AND_FALL_EDGE    0x3
-#define INTC_INT_HIGH_LEVEL            0x5
-#define INTC_INT_LOW_LEVEL             0x6
-#define INTC_INT_HIGH_AND_LOW_LEVEL    0x7
+#define INTC_INT_DISABLED		0x0
+#define INTC_INT_RISE_EDGE		0x1
+#define INTC_INT_FALL_EDGE		0x2
+#define INTC_INT_RISE_AND_FALL_EDGE	0x3
+#define INTC_INT_HIGH_LEVEL		0x5
+#define INTC_INT_LOW_LEVEL		0x6
+#define INTC_INT_HIGH_AND_LOW_LEVEL	0x7
 
 /* Interrupt Numbers */
 /* Au1000 */
@@ -579,18 +579,18 @@
 	AU1000_GPIO_31,
 };
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-#define UART2_ADDR                0xB1300000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR		0xB1100000
+#define UART1_ADDR		0xB1200000
+#define UART2_ADDR		0xB1300000
+#define UART3_ADDR		0xB1400000
 
-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
-#define USB_HOST_CONFIG           0xB017fffc
+#define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
+#define USB_HOST_CONFIG 	0xB017FFFC
 
-#define AU1000_ETH0_BASE      0xB0500000
-#define AU1000_ETH1_BASE      0xB0510000
-#define AU1000_MAC0_ENABLE       0xB0520000
-#define AU1000_MAC1_ENABLE       0xB0520004
+#define AU1000_ETH0_BASE	0xB0500000
+#define AU1000_ETH1_BASE	0xB0510000
+#define AU1000_MAC0_ENABLE	0xB0520000
+#define AU1000_MAC1_ENABLE	0xB0520004
 #define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1000 */
 
@@ -662,16 +662,16 @@
 #define INTC AU1000_PCI_INTC
 #define INTD AU1000_PCI_INTD
 
-#define UART0_ADDR                0xB1100000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR		0xB1100000
+#define UART3_ADDR		0xB1400000
 
-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
-#define USB_HOST_CONFIG           0xB017fffc
+#define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
+#define USB_HOST_CONFIG 	0xB017fffc
 
-#define AU1500_ETH0_BASE	  0xB1500000
-#define AU1500_ETH1_BASE	  0xB1510000
-#define AU1500_MAC0_ENABLE       0xB1520000
-#define AU1500_MAC1_ENABLE       0xB1520004
+#define AU1500_ETH0_BASE	0xB1500000
+#define AU1500_ETH1_BASE	0xB1510000
+#define AU1500_MAC0_ENABLE	0xB1520000
+#define AU1500_MAC1_ENABLE	0xB1520004
 #define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1500 */
 
@@ -739,15 +739,15 @@
 	AU1000_GPIO_31,
 };
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR		0xB1100000
+#define UART1_ADDR		0xB1200000
+#define UART3_ADDR		0xB1400000
 
-#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
-#define USB_HOST_CONFIG           0xB017fffc
+#define USB_OHCI_BASE		0x10100000	/* phys addr for ioremap */
+#define USB_HOST_CONFIG 	0xB017FFFC
 
-#define AU1100_ETH0_BASE	  0xB0500000
-#define AU1100_MAC0_ENABLE       0xB0520000
+#define AU1100_ETH0_BASE	0xB0500000
+#define AU1100_MAC0_ENABLE	0xB0520000
 #define NUM_ETH_INTERFACES 1
 #endif /* CONFIG_SOC_AU1100 */
 
@@ -826,18 +826,18 @@
 #define INTC AU1550_PCI_INTC
 #define INTD AU1550_PCI_INTD
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-#define UART3_ADDR                0xB1400000
+#define UART0_ADDR		0xB1100000
+#define UART1_ADDR		0xB1200000
+#define UART3_ADDR		0xB1400000
 
-#define USB_OHCI_BASE             0x14020000 // phys addr for ioremap
-#define USB_OHCI_LEN              0x00060000
-#define USB_HOST_CONFIG           0xB4027ffc
+#define USB_OHCI_BASE		0x14020000	/* phys addr for ioremap */
+#define USB_OHCI_LEN		0x00060000
+#define USB_HOST_CONFIG 	0xB4027ffc
 
-#define AU1550_ETH0_BASE      0xB0500000
-#define AU1550_ETH1_BASE      0xB0510000
-#define AU1550_MAC0_ENABLE       0xB0520000
-#define AU1550_MAC1_ENABLE       0xB0520004
+#define AU1550_ETH0_BASE	0xB0500000
+#define AU1550_ETH1_BASE	0xB0510000
+#define AU1550_MAC0_ENABLE	0xB0520000
+#define AU1550_MAC1_ENABLE	0xB0520004
 #define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1550 */
 
@@ -911,32 +911,32 @@
 	AU1000_GPIO_31,
 };
 
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
+#define UART0_ADDR		0xB1100000
+#define UART1_ADDR		0xB1200000
 
-#define USB_UOC_BASE              0x14020020
-#define USB_UOC_LEN               0x20
-#define USB_OHCI_BASE             0x14020100
-#define USB_OHCI_LEN              0x100
-#define USB_EHCI_BASE             0x14020200
-#define USB_EHCI_LEN              0x100
-#define USB_UDC_BASE              0x14022000
-#define USB_UDC_LEN               0x2000
-#define USB_MSR_BASE			  0xB4020000
-#define USB_MSR_MCFG              4
-#define USBMSRMCFG_OMEMEN         0
-#define USBMSRMCFG_OBMEN          1
-#define USBMSRMCFG_EMEMEN         2
-#define USBMSRMCFG_EBMEN          3
-#define USBMSRMCFG_DMEMEN         4
-#define USBMSRMCFG_DBMEN          5
-#define USBMSRMCFG_GMEMEN         6
-#define USBMSRMCFG_OHCCLKEN       16
-#define USBMSRMCFG_EHCCLKEN       17
-#define USBMSRMCFG_UDCCLKEN       18
-#define USBMSRMCFG_PHYPLLEN       19
-#define USBMSRMCFG_RDCOMB         30
-#define USBMSRMCFG_PFEN           31
+#define USB_UOC_BASE		0x14020020
+#define USB_UOC_LEN		0x20
+#define USB_OHCI_BASE		0x14020100
+#define USB_OHCI_LEN		0x100
+#define USB_EHCI_BASE		0x14020200
+#define USB_EHCI_LEN		0x100
+#define USB_UDC_BASE		0x14022000
+#define USB_UDC_LEN		0x2000
+#define USB_MSR_BASE		0xB4020000
+#define USB_MSR_MCFG		4
+#define USBMSRMCFG_OMEMEN	0
+#define USBMSRMCFG_OBMEN	1
+#define USBMSRMCFG_EMEMEN	2
+#define USBMSRMCFG_EBMEN	3
+#define USBMSRMCFG_DMEMEN	4
+#define USBMSRMCFG_DBMEN	5
+#define USBMSRMCFG_GMEMEN	6
+#define USBMSRMCFG_OHCCLKEN	16
+#define USBMSRMCFG_EHCCLKEN	17
+#define USBMSRMCFG_UDCCLKEN	18
+#define USBMSRMCFG_PHYPLLEN	19
+#define USBMSRMCFG_RDCOMB	30
+#define USBMSRMCFG_PFEN 	31
 
 #endif /* CONFIG_SOC_AU1200 */
 
@@ -949,259 +949,258 @@
 #define INTX			0xFF			/* not valid */
 
 /* Programmable Counters 0 and 1 */
-#define SYS_BASE                   0xB1900000
-#define SYS_COUNTER_CNTRL          (SYS_BASE + 0x14)
-#  define SYS_CNTRL_E1S            (1<<23)
-#  define SYS_CNTRL_T1S            (1<<20)
-#  define SYS_CNTRL_M21            (1<<19)
-#  define SYS_CNTRL_M11            (1<<18)
-#  define SYS_CNTRL_M01            (1<<17)
-#  define SYS_CNTRL_C1S            (1<<16)
-#  define SYS_CNTRL_BP             (1<<14)
-#  define SYS_CNTRL_EN1            (1<<13)
-#  define SYS_CNTRL_BT1            (1<<12)
-#  define SYS_CNTRL_EN0            (1<<11)
-#  define SYS_CNTRL_BT0            (1<<10)
-#  define SYS_CNTRL_E0             (1<<8)
-#  define SYS_CNTRL_E0S            (1<<7)
-#  define SYS_CNTRL_32S            (1<<5)
-#  define SYS_CNTRL_T0S            (1<<4)
-#  define SYS_CNTRL_M20            (1<<3)
-#  define SYS_CNTRL_M10            (1<<2)
-#  define SYS_CNTRL_M00            (1<<1)
-#  define SYS_CNTRL_C0S            (1<<0)
+#define SYS_BASE		0xB1900000
+#define SYS_COUNTER_CNTRL	(SYS_BASE + 0x14)
+#  define SYS_CNTRL_E1S 	(1 << 23)
+#  define SYS_CNTRL_T1S 	(1 << 20)
+#  define SYS_CNTRL_M21 	(1 << 19)
+#  define SYS_CNTRL_M11 	(1 << 18)
+#  define SYS_CNTRL_M01 	(1 << 17)
+#  define SYS_CNTRL_C1S 	(1 << 16)
+#  define SYS_CNTRL_BP		(1 << 14)
+#  define SYS_CNTRL_EN1 	(1 << 13)
+#  define SYS_CNTRL_BT1 	(1 << 12)
+#  define SYS_CNTRL_EN0 	(1 << 11)
+#  define SYS_CNTRL_BT0 	(1 << 10)
+#  define SYS_CNTRL_E0		(1 << 8)
+#  define SYS_CNTRL_E0S 	(1 << 7)
+#  define SYS_CNTRL_32S 	(1 << 5)
+#  define SYS_CNTRL_T0S 	(1 << 4)
+#  define SYS_CNTRL_M20 	(1 << 3)
+#  define SYS_CNTRL_M10 	(1 << 2)
+#  define SYS_CNTRL_M00 	(1 << 1)
+#  define SYS_CNTRL_C0S 	(1 << 0)
 
 /* Programmable Counter 0 Registers */
-#define SYS_TOYTRIM                 (SYS_BASE + 0)
-#define SYS_TOYWRITE                (SYS_BASE + 4)
-#define SYS_TOYMATCH0               (SYS_BASE + 8)
-#define SYS_TOYMATCH1               (SYS_BASE + 0xC)
-#define SYS_TOYMATCH2               (SYS_BASE + 0x10)
-#define SYS_TOYREAD                 (SYS_BASE + 0x40)
+#define SYS_TOYTRIM		(SYS_BASE + 0)
+#define SYS_TOYWRITE		(SYS_BASE + 4)
+#define SYS_TOYMATCH0		(SYS_BASE + 8)
+#define SYS_TOYMATCH1		(SYS_BASE + 0xC)
+#define SYS_TOYMATCH2		(SYS_BASE + 0x10)
+#define SYS_TOYREAD		(SYS_BASE + 0x40)
 
 /* Programmable Counter 1 Registers */
-#define SYS_RTCTRIM                 (SYS_BASE + 0x44)
-#define SYS_RTCWRITE                (SYS_BASE + 0x48)
-#define SYS_RTCMATCH0               (SYS_BASE + 0x4C)
-#define SYS_RTCMATCH1               (SYS_BASE + 0x50)
-#define SYS_RTCMATCH2               (SYS_BASE + 0x54)
-#define SYS_RTCREAD                 (SYS_BASE + 0x58)
+#define SYS_RTCTRIM		(SYS_BASE + 0x44)
+#define SYS_RTCWRITE		(SYS_BASE + 0x48)
+#define SYS_RTCMATCH0		(SYS_BASE + 0x4C)
+#define SYS_RTCMATCH1		(SYS_BASE + 0x50)
+#define SYS_RTCMATCH2		(SYS_BASE + 0x54)
+#define SYS_RTCREAD		(SYS_BASE + 0x58)
 
 /* I2S Controller */
-#define I2S_DATA                    0xB1000000
-#  define I2S_DATA_MASK        (0xffffff)
-#define I2S_CONFIG                0xB1000004
-#  define I2S_CONFIG_XU        (1<<25)
-#  define I2S_CONFIG_XO        (1<<24)
-#  define I2S_CONFIG_RU        (1<<23)
-#  define I2S_CONFIG_RO        (1<<22)
-#  define I2S_CONFIG_TR        (1<<21)
-#  define I2S_CONFIG_TE        (1<<20)
-#  define I2S_CONFIG_TF        (1<<19)
-#  define I2S_CONFIG_RR        (1<<18)
-#  define I2S_CONFIG_RE        (1<<17)
-#  define I2S_CONFIG_RF        (1<<16)
-#  define I2S_CONFIG_PD        (1<<11)
-#  define I2S_CONFIG_LB        (1<<10)
-#  define I2S_CONFIG_IC        (1<<9)
-#  define I2S_CONFIG_FM_BIT    7
-#  define I2S_CONFIG_FM_MASK     (0x3 << I2S_CONFIG_FM_BIT)
-#    define I2S_CONFIG_FM_I2S    (0x0 << I2S_CONFIG_FM_BIT)
-#    define I2S_CONFIG_FM_LJ     (0x1 << I2S_CONFIG_FM_BIT)
-#    define I2S_CONFIG_FM_RJ     (0x2 << I2S_CONFIG_FM_BIT)
-#  define I2S_CONFIG_TN        (1<<6)
-#  define I2S_CONFIG_RN        (1<<5)
-#  define I2S_CONFIG_SZ_BIT    0
-#  define I2S_CONFIG_SZ_MASK     (0x1F << I2S_CONFIG_SZ_BIT)
+#define I2S_DATA		0xB1000000
+#  define I2S_DATA_MASK 	0xffffff
+#define I2S_CONFIG		0xB1000004
+#  define I2S_CONFIG_XU 	(1 << 25)
+#  define I2S_CONFIG_XO 	(1 << 24)
+#  define I2S_CONFIG_RU 	(1 << 23)
+#  define I2S_CONFIG_RO 	(1 << 22)
+#  define I2S_CONFIG_TR 	(1 << 21)
+#  define I2S_CONFIG_TE 	(1 << 20)
+#  define I2S_CONFIG_TF 	(1 << 19)
+#  define I2S_CONFIG_RR 	(1 << 18)
+#  define I2S_CONFIG_RE 	(1 << 17)
+#  define I2S_CONFIG_RF 	(1 << 16)
+#  define I2S_CONFIG_PD 	(1 << 11)
+#  define I2S_CONFIG_LB 	(1 << 10)
+#  define I2S_CONFIG_IC 	(1 << 9)
+#  define I2S_CONFIG_FM_BIT	7
+#  define I2S_CONFIG_FM_MASK	(0x3 << I2S_CONFIG_FM_BIT)
+#    define I2S_CONFIG_FM_I2S	(0x0 << I2S_CONFIG_FM_BIT)
+#    define I2S_CONFIG_FM_LJ	(0x1 << I2S_CONFIG_FM_BIT)
+#    define I2S_CONFIG_FM_RJ	(0x2 << I2S_CONFIG_FM_BIT)
+#  define I2S_CONFIG_TN 	(1 << 6)
+#  define I2S_CONFIG_RN 	(1 << 5)
+#  define I2S_CONFIG_SZ_BIT	0
+#  define I2S_CONFIG_SZ_MASK	(0x1F << I2S_CONFIG_SZ_BIT)
 
-#define I2S_CONTROL                0xB1000008
-#  define I2S_CONTROL_D         (1<<1)
-#  define I2S_CONTROL_CE        (1<<0)
+#define I2S_CONTROL		0xB1000008
+#  define I2S_CONTROL_D 	(1 << 1)
+#  define I2S_CONTROL_CE	(1 << 0)
 
 /* USB Host Controller */
 #ifndef USB_OHCI_LEN
-#define USB_OHCI_LEN              0x00100000
+#define USB_OHCI_LEN		0x00100000
 #endif
 
 #ifndef CONFIG_SOC_AU1200
 
 /* USB Device Controller */
-#define USBD_EP0RD                0xB0200000
-#define USBD_EP0WR                0xB0200004
-#define USBD_EP2WR                0xB0200008
-#define USBD_EP3WR                0xB020000C
-#define USBD_EP4RD                0xB0200010
-#define USBD_EP5RD                0xB0200014
-#define USBD_INTEN                0xB0200018
-#define USBD_INTSTAT              0xB020001C
-#  define USBDEV_INT_SOF       (1<<12)
-#  define USBDEV_INT_HF_BIT    6
-#  define USBDEV_INT_HF_MASK   (0x3f << USBDEV_INT_HF_BIT)
-#  define USBDEV_INT_CMPLT_BIT  0
+#define USBD_EP0RD		0xB0200000
+#define USBD_EP0WR		0xB0200004
+#define USBD_EP2WR		0xB0200008
+#define USBD_EP3WR		0xB020000C
+#define USBD_EP4RD		0xB0200010
+#define USBD_EP5RD		0xB0200014
+#define USBD_INTEN		0xB0200018
+#define USBD_INTSTAT		0xB020001C
+#  define USBDEV_INT_SOF	(1 << 12)
+#  define USBDEV_INT_HF_BIT	6
+#  define USBDEV_INT_HF_MASK	0x3f << USBDEV_INT_HF_BIT)
+#  define USBDEV_INT_CMPLT_BIT	0
 #  define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT)
-#define USBD_CONFIG               0xB0200020
-#define USBD_EP0CS                0xB0200024
-#define USBD_EP2CS                0xB0200028
-#define USBD_EP3CS                0xB020002C
-#define USBD_EP4CS                0xB0200030
-#define USBD_EP5CS                0xB0200034
-#  define USBDEV_CS_SU         (1<<14)
-#  define USBDEV_CS_NAK        (1<<13)
-#  define USBDEV_CS_ACK        (1<<12)
-#  define USBDEV_CS_BUSY       (1<<11)
-#  define USBDEV_CS_TSIZE_BIT  1
-#  define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT)
-#  define USBDEV_CS_STALL      (1<<0)
-#define USBD_EP0RDSTAT            0xB0200040
-#define USBD_EP0WRSTAT            0xB0200044
-#define USBD_EP2WRSTAT            0xB0200048
-#define USBD_EP3WRSTAT            0xB020004C
-#define USBD_EP4RDSTAT            0xB0200050
-#define USBD_EP5RDSTAT            0xB0200054
-#  define USBDEV_FSTAT_FLUSH     (1<<6)
-#  define USBDEV_FSTAT_UF        (1<<5)
-#  define USBDEV_FSTAT_OF        (1<<4)
-#  define USBDEV_FSTAT_FCNT_BIT  0
+#define USBD_CONFIG		0xB0200020
+#define USBD_EP0CS		0xB0200024
+#define USBD_EP2CS		0xB0200028
+#define USBD_EP3CS		0xB020002C
+#define USBD_EP4CS		0xB0200030
+#define USBD_EP5CS		0xB0200034
+#  define USBDEV_CS_SU		(1 << 14)
+#  define USBDEV_CS_NAK 	(1 << 13)
+#  define USBDEV_CS_ACK 	(1 << 12)
+#  define USBDEV_CS_BUSY	(1 << 11)
+#  define USBDEV_CS_TSIZE_BIT	1
+#  define USBDEV_CS_TSIZE_MASK	(0x3ff << USBDEV_CS_TSIZE_BIT)
+#  define USBDEV_CS_STALL	(1 << 0)
+#define USBD_EP0RDSTAT		0xB0200040
+#define USBD_EP0WRSTAT		0xB0200044
+#define USBD_EP2WRSTAT		0xB0200048
+#define USBD_EP3WRSTAT		0xB020004C
+#define USBD_EP4RDSTAT		0xB0200050
+#define USBD_EP5RDSTAT		0xB0200054
+#  define USBDEV_FSTAT_FLUSH	(1 << 6)
+#  define USBDEV_FSTAT_UF	(1 << 5)
+#  define USBDEV_FSTAT_OF	(1 << 4)
+#  define USBDEV_FSTAT_FCNT_BIT 0
 #  define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT)
-#define USBD_ENABLE               0xB0200058
-#  define USBDEV_ENABLE (1<<1)
-#  define USBDEV_CE     (1<<0)
+#define USBD_ENABLE		0xB0200058
+#  define USBDEV_ENABLE 	(1 << 1)
+#  define USBDEV_CE		(1 << 0)
 
 #endif /* !CONFIG_SOC_AU1200 */
 
 /* Ethernet Controllers  */
 
 /* 4 byte offsets from AU1000_ETH_BASE */
-#define MAC_CONTROL                     0x0
-#  define MAC_RX_ENABLE               (1<<2)
-#  define MAC_TX_ENABLE               (1<<3)
-#  define MAC_DEF_CHECK               (1<<5)
-#  define MAC_SET_BL(X)       (((X)&0x3)<<6)
-#  define MAC_AUTO_PAD                (1<<8)
-#  define MAC_DISABLE_RETRY          (1<<10)
-#  define MAC_DISABLE_BCAST          (1<<11)
-#  define MAC_LATE_COL               (1<<12)
-#  define MAC_HASH_MODE              (1<<13)
-#  define MAC_HASH_ONLY              (1<<15)
-#  define MAC_PASS_ALL               (1<<16)
-#  define MAC_INVERSE_FILTER         (1<<17)
-#  define MAC_PROMISCUOUS            (1<<18)
-#  define MAC_PASS_ALL_MULTI         (1<<19)
-#  define MAC_FULL_DUPLEX            (1<<20)
-#  define MAC_NORMAL_MODE                 0
-#  define MAC_INT_LOOPBACK           (1<<21)
-#  define MAC_EXT_LOOPBACK           (1<<22)
-#  define MAC_DISABLE_RX_OWN         (1<<23)
-#  define MAC_BIG_ENDIAN             (1<<30)
-#  define MAC_RX_ALL                 (1<<31)
-#define MAC_ADDRESS_HIGH                0x4
-#define MAC_ADDRESS_LOW                 0x8
-#define MAC_MCAST_HIGH                  0xC
-#define MAC_MCAST_LOW                  0x10
-#define MAC_MII_CNTRL                  0x14
-#  define MAC_MII_BUSY                (1<<0)
-#  define MAC_MII_READ                     0
-#  define MAC_MII_WRITE               (1<<1)
-#  define MAC_SET_MII_SELECT_REG(X)   (((X)&0x1f)<<6)
-#  define MAC_SET_MII_SELECT_PHY(X)   (((X)&0x1f)<<11)
-#define MAC_MII_DATA                   0x18
-#define MAC_FLOW_CNTRL                 0x1C
-#  define MAC_FLOW_CNTRL_BUSY         (1<<0)
-#  define MAC_FLOW_CNTRL_ENABLE       (1<<1)
-#  define MAC_PASS_CONTROL            (1<<2)
-#  define MAC_SET_PAUSE(X)        (((X)&0xffff)<<16)
-#define MAC_VLAN1_TAG                  0x20
-#define MAC_VLAN2_TAG                  0x24
+#define MAC_CONTROL		0x0
+#  define MAC_RX_ENABLE 	(1 << 2)
+#  define MAC_TX_ENABLE 	(1 << 3)
+#  define MAC_DEF_CHECK 	(1 << 5)
+#  define MAC_SET_BL(X) 	(((X) & 0x3) << 6)
+#  define MAC_AUTO_PAD		(1 << 8)
+#  define MAC_DISABLE_RETRY	(1 << 10)
+#  define MAC_DISABLE_BCAST	(1 << 11)
+#  define MAC_LATE_COL		(1 << 12)
+#  define MAC_HASH_MODE 	(1 << 13)
+#  define MAC_HASH_ONLY 	(1 << 15)
+#  define MAC_PASS_ALL		(1 << 16)
+#  define MAC_INVERSE_FILTER	(1 << 17)
+#  define MAC_PROMISCUOUS	(1 << 18)
+#  define MAC_PASS_ALL_MULTI	(1 << 19)
+#  define MAC_FULL_DUPLEX	(1 << 20)
+#  define MAC_NORMAL_MODE	0
+#  define MAC_INT_LOOPBACK	(1 << 21)
+#  define MAC_EXT_LOOPBACK	(1 << 22)
+#  define MAC_DISABLE_RX_OWN	(1 << 23)
+#  define MAC_BIG_ENDIAN	(1 << 30)
+#  define MAC_RX_ALL		(1 << 31)
+#define MAC_ADDRESS_HIGH	0x4
+#define MAC_ADDRESS_LOW		0x8
+#define MAC_MCAST_HIGH		0xC
+#define MAC_MCAST_LOW		0x10
+#define MAC_MII_CNTRL		0x14
+#  define MAC_MII_BUSY		(1 << 0)
+#  define MAC_MII_READ		0
+#  define MAC_MII_WRITE		(1 << 1)
+#  define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6)
+#  define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11)
+#define MAC_MII_DATA		0x18
+#define MAC_FLOW_CNTRL		0x1C
+#  define MAC_FLOW_CNTRL_BUSY	(1 << 0)
+#  define MAC_FLOW_CNTRL_ENABLE (1 << 1)
+#  define MAC_PASS_CONTROL	(1 << 2)
+#  define MAC_SET_PAUSE(X)	(((X) & 0xffff) << 16)
+#define MAC_VLAN1_TAG		0x20
+#define MAC_VLAN2_TAG		0x24
 
 /* Ethernet Controller Enable */
 
-#  define MAC_EN_CLOCK_ENABLE         (1<<0)
-#  define MAC_EN_RESET0               (1<<1)
-#  define MAC_EN_TOSS                 (0<<2)
-#  define MAC_EN_CACHEABLE            (1<<3)
-#  define MAC_EN_RESET1               (1<<4)
-#  define MAC_EN_RESET2               (1<<5)
-#  define MAC_DMA_RESET               (1<<6)
+#  define MAC_EN_CLOCK_ENABLE	(1 << 0)
+#  define MAC_EN_RESET0		(1 << 1)
+#  define MAC_EN_TOSS		(0 << 2)
+#  define MAC_EN_CACHEABLE	(1 << 3)
+#  define MAC_EN_RESET1 	(1 << 4)
+#  define MAC_EN_RESET2 	(1 << 5)
+#  define MAC_DMA_RESET 	(1 << 6)
 
 /* Ethernet Controller DMA Channels */
 
-#define MAC0_TX_DMA_ADDR         0xB4004000
-#define MAC1_TX_DMA_ADDR         0xB4004200
+#define MAC0_TX_DMA_ADDR	0xB4004000
+#define MAC1_TX_DMA_ADDR	0xB4004200
 /* offsets from MAC_TX_RING_ADDR address */
-#define MAC_TX_BUFF0_STATUS             0x0
-#  define TX_FRAME_ABORTED            (1<<0)
-#  define TX_JAB_TIMEOUT              (1<<1)
-#  define TX_NO_CARRIER               (1<<2)
-#  define TX_LOSS_CARRIER             (1<<3)
-#  define TX_EXC_DEF                  (1<<4)
-#  define TX_LATE_COLL_ABORT          (1<<5)
-#  define TX_EXC_COLL                 (1<<6)
-#  define TX_UNDERRUN                 (1<<7)
-#  define TX_DEFERRED                 (1<<8)
-#  define TX_LATE_COLL                (1<<9)
-#  define TX_COLL_CNT_MASK         (0xF<<10)
-#  define TX_PKT_RETRY               (1<<31)
-#define MAC_TX_BUFF0_ADDR                0x4
-#  define TX_DMA_ENABLE               (1<<0)
-#  define TX_T_DONE                   (1<<1)
-#  define TX_GET_DMA_BUFFER(X)    (((X)>>2)&0x3)
-#define MAC_TX_BUFF0_LEN                 0x8
-#define MAC_TX_BUFF1_STATUS             0x10
-#define MAC_TX_BUFF1_ADDR               0x14
-#define MAC_TX_BUFF1_LEN                0x18
-#define MAC_TX_BUFF2_STATUS             0x20
-#define MAC_TX_BUFF2_ADDR               0x24
-#define MAC_TX_BUFF2_LEN                0x28
-#define MAC_TX_BUFF3_STATUS             0x30
-#define MAC_TX_BUFF3_ADDR               0x34
-#define MAC_TX_BUFF3_LEN                0x38
+#define MAC_TX_BUFF0_STATUS	0x0
+#  define TX_FRAME_ABORTED	(1 << 0)
+#  define TX_JAB_TIMEOUT	(1 << 1)
+#  define TX_NO_CARRIER 	(1 << 2)
+#  define TX_LOSS_CARRIER	(1 << 3)
+#  define TX_EXC_DEF		(1 << 4)
+#  define TX_LATE_COLL_ABORT	(1 << 5)
+#  define TX_EXC_COLL		(1 << 6)
+#  define TX_UNDERRUN		(1 << 7)
+#  define TX_DEFERRED		(1 << 8)
+#  define TX_LATE_COLL		(1 << 9)
+#  define TX_COLL_CNT_MASK	(0xF << 10)
+#  define TX_PKT_RETRY		(1 << 31)
+#define MAC_TX_BUFF0_ADDR	0x4
+#  define TX_DMA_ENABLE 	(1 << 0)
+#  define TX_T_DONE		(1 << 1)
+#  define TX_GET_DMA_BUFFER(X)	(((X) >> 2) & 0x3)
+#define MAC_TX_BUFF0_LEN	0x8
+#define MAC_TX_BUFF1_STATUS	0x10
+#define MAC_TX_BUFF1_ADDR	0x14
+#define MAC_TX_BUFF1_LEN	0x18
+#define MAC_TX_BUFF2_STATUS	0x20
+#define MAC_TX_BUFF2_ADDR	0x24
+#define MAC_TX_BUFF2_LEN	0x28
+#define MAC_TX_BUFF3_STATUS	0x30
+#define MAC_TX_BUFF3_ADDR	0x34
+#define MAC_TX_BUFF3_LEN	0x38
 
-#define MAC0_RX_DMA_ADDR         0xB4004100
-#define MAC1_RX_DMA_ADDR         0xB4004300
+#define MAC0_RX_DMA_ADDR	0xB4004100
+#define MAC1_RX_DMA_ADDR	0xB4004300
 /* offsets from MAC_RX_RING_ADDR */
-#define MAC_RX_BUFF0_STATUS              0x0
-#  define RX_FRAME_LEN_MASK           0x3fff
-#  define RX_WDOG_TIMER              (1<<14)
-#  define RX_RUNT                    (1<<15)
-#  define RX_OVERLEN                 (1<<16)
-#  define RX_COLL                    (1<<17)
-#  define RX_ETHER                   (1<<18)
-#  define RX_MII_ERROR               (1<<19)
-#  define RX_DRIBBLING               (1<<20)
-#  define RX_CRC_ERROR               (1<<21)
-#  define RX_VLAN1                   (1<<22)
-#  define RX_VLAN2                   (1<<23)
-#  define RX_LEN_ERROR               (1<<24)
-#  define RX_CNTRL_FRAME             (1<<25)
-#  define RX_U_CNTRL_FRAME           (1<<26)
-#  define RX_MCAST_FRAME             (1<<27)
-#  define RX_BCAST_FRAME             (1<<28)
-#  define RX_FILTER_FAIL             (1<<29)
-#  define RX_PACKET_FILTER           (1<<30)
-#  define RX_MISSED_FRAME            (1<<31)
+#define MAC_RX_BUFF0_STATUS	0x0
+#  define RX_FRAME_LEN_MASK	0x3fff
+#  define RX_WDOG_TIMER 	(1 << 14)
+#  define RX_RUNT		(1 << 15)
+#  define RX_OVERLEN		(1 << 16)
+#  define RX_COLL		(1 << 17)
+#  define RX_ETHER		(1 << 18)
+#  define RX_MII_ERROR		(1 << 19)
+#  define RX_DRIBBLING		(1 << 20)
+#  define RX_CRC_ERROR		(1 << 21)
+#  define RX_VLAN1		(1 << 22)
+#  define RX_VLAN2		(1 << 23)
+#  define RX_LEN_ERROR		(1 << 24)
+#  define RX_CNTRL_FRAME	(1 << 25)
+#  define RX_U_CNTRL_FRAME	(1 << 26)
+#  define RX_MCAST_FRAME	(1 << 27)
+#  define RX_BCAST_FRAME	(1 << 28)
+#  define RX_FILTER_FAIL	(1 << 29)
+#  define RX_PACKET_FILTER	(1 << 30)
+#  define RX_MISSED_FRAME	(1 << 31)
 
 #  define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN |  \
-                    RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
-                    RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
-#define MAC_RX_BUFF0_ADDR                0x4
-#  define RX_DMA_ENABLE               (1<<0)
-#  define RX_T_DONE                   (1<<1)
-#  define RX_GET_DMA_BUFFER(X)    (((X)>>2)&0x3)
-#  define RX_SET_BUFF_ADDR(X)     ((X)&0xffffffc0)
-#define MAC_RX_BUFF1_STATUS              0x10
-#define MAC_RX_BUFF1_ADDR                0x14
-#define MAC_RX_BUFF2_STATUS              0x20
-#define MAC_RX_BUFF2_ADDR                0x24
-#define MAC_RX_BUFF3_STATUS              0x30
-#define MAC_RX_BUFF3_ADDR                0x34
-
+		    RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
+		    RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
+#define MAC_RX_BUFF0_ADDR	0x4
+#  define RX_DMA_ENABLE 	(1 << 0)
+#  define RX_T_DONE		(1 << 1)
+#  define RX_GET_DMA_BUFFER(X)	(((X) >> 2) & 0x3)
+#  define RX_SET_BUFF_ADDR(X)	((X) & 0xffffffc0)
+#define MAC_RX_BUFF1_STATUS	0x10
+#define MAC_RX_BUFF1_ADDR	0x14
+#define MAC_RX_BUFF2_STATUS	0x20
+#define MAC_RX_BUFF2_ADDR	0x24
+#define MAC_RX_BUFF3_STATUS	0x30
+#define MAC_RX_BUFF3_ADDR	0x34
 
 /* UARTS 0-3 */
-#define UART_BASE                 UART0_ADDR
+#define UART_BASE		UART0_ADDR
 #ifdef	CONFIG_SOC_AU1200
-#define UART_DEBUG_BASE           UART1_ADDR
+#define UART_DEBUG_BASE 	UART1_ADDR
 #else
-#define UART_DEBUG_BASE           UART3_ADDR
+#define UART_DEBUG_BASE 	UART3_ADDR
 #endif
 
 #define UART_RX		0	/* Receive buffer */
@@ -1294,341 +1293,337 @@
 #define UART_MSR_DCTS	0x01	/* Delta CTS */
 #define UART_MSR_ANY_DELTA 0x0F	/* Any of the delta bits! */
 
-
-
 /* SSIO */
-#define SSI0_STATUS                0xB1600000
-#  define SSI_STATUS_BF              (1<<4)
-#  define SSI_STATUS_OF              (1<<3)
-#  define SSI_STATUS_UF              (1<<2)
-#  define SSI_STATUS_D               (1<<1)
-#  define SSI_STATUS_B               (1<<0)
-#define SSI0_INT                   0xB1600004
-#  define SSI_INT_OI                 (1<<3)
-#  define SSI_INT_UI                 (1<<2)
-#  define SSI_INT_DI                 (1<<1)
-#define SSI0_INT_ENABLE            0xB1600008
-#  define SSI_INTE_OIE               (1<<3)
-#  define SSI_INTE_UIE               (1<<2)
-#  define SSI_INTE_DIE               (1<<1)
-#define SSI0_CONFIG                0xB1600020
-#  define SSI_CONFIG_AO              (1<<24)
-#  define SSI_CONFIG_DO              (1<<23)
-#  define SSI_CONFIG_ALEN_BIT        20
-#    define SSI_CONFIG_ALEN_MASK       (0x7<<20)
-#  define SSI_CONFIG_DLEN_BIT        16
-#    define SSI_CONFIG_DLEN_MASK       (0x7<<16)
-#  define SSI_CONFIG_DD              (1<<11)
-#  define SSI_CONFIG_AD              (1<<10)
-#  define SSI_CONFIG_BM_BIT          8
-#    define SSI_CONFIG_BM_MASK         (0x3<<8)
-#  define SSI_CONFIG_CE              (1<<7)
-#  define SSI_CONFIG_DP              (1<<6)
-#  define SSI_CONFIG_DL              (1<<5)
-#  define SSI_CONFIG_EP              (1<<4)
-#define SSI0_ADATA                 0xB1600024
-#  define SSI_AD_D                   (1<<24)
-#  define SSI_AD_ADDR_BIT            16
-#    define SSI_AD_ADDR_MASK           (0xff<<16)
-#  define SSI_AD_DATA_BIT            0
-#    define SSI_AD_DATA_MASK           (0xfff<<0)
-#define SSI0_CLKDIV                0xB1600028
-#define SSI0_CONTROL               0xB1600100
-#  define SSI_CONTROL_CD             (1<<1)
-#  define SSI_CONTROL_E              (1<<0)
+#define SSI0_STATUS		0xB1600000
+#  define SSI_STATUS_BF 	(1 << 4)
+#  define SSI_STATUS_OF 	(1 << 3)
+#  define SSI_STATUS_UF 	(1 << 2)
+#  define SSI_STATUS_D		(1 << 1)
+#  define SSI_STATUS_B		(1 << 0)
+#define SSI0_INT		0xB1600004
+#  define SSI_INT_OI		(1 << 3)
+#  define SSI_INT_UI		(1 << 2)
+#  define SSI_INT_DI		(1 << 1)
+#define SSI0_INT_ENABLE 	0xB1600008
+#  define SSI_INTE_OIE		(1 << 3)
+#  define SSI_INTE_UIE		(1 << 2)
+#  define SSI_INTE_DIE		(1 << 1)
+#define SSI0_CONFIG		0xB1600020
+#  define SSI_CONFIG_AO 	(1 << 24)
+#  define SSI_CONFIG_DO 	(1 << 23)
+#  define SSI_CONFIG_ALEN_BIT	20
+#  define SSI_CONFIG_ALEN_MASK	(0x7 << 20)
+#  define SSI_CONFIG_DLEN_BIT	16
+#  define SSI_CONFIG_DLEN_MASK	(0x7 << 16)
+#  define SSI_CONFIG_DD 	(1 << 11)
+#  define SSI_CONFIG_AD 	(1 << 10)
+#  define SSI_CONFIG_BM_BIT	8
+#  define SSI_CONFIG_BM_MASK	(0x3 << 8)
+#  define SSI_CONFIG_CE 	(1 << 7)
+#  define SSI_CONFIG_DP 	(1 << 6)
+#  define SSI_CONFIG_DL 	(1 << 5)
+#  define SSI_CONFIG_EP 	(1 << 4)
+#define SSI0_ADATA		0xB1600024
+#  define SSI_AD_D		(1 << 24)
+#  define SSI_AD_ADDR_BIT	16
+#  define SSI_AD_ADDR_MASK	(0xff << 16)
+#  define SSI_AD_DATA_BIT	0
+#  define SSI_AD_DATA_MASK	(0xfff << 0)
+#define SSI0_CLKDIV		0xB1600028
+#define SSI0_CONTROL		0xB1600100
+#  define SSI_CONTROL_CD	(1 << 1)
+#  define SSI_CONTROL_E 	(1 << 0)
 
 /* SSI1 */
-#define SSI1_STATUS                0xB1680000
-#define SSI1_INT                   0xB1680004
-#define SSI1_INT_ENABLE            0xB1680008
-#define SSI1_CONFIG                0xB1680020
-#define SSI1_ADATA                 0xB1680024
-#define SSI1_CLKDIV                0xB1680028
-#define SSI1_ENABLE                0xB1680100
+#define SSI1_STATUS		0xB1680000
+#define SSI1_INT		0xB1680004
+#define SSI1_INT_ENABLE 	0xB1680008
+#define SSI1_CONFIG		0xB1680020
+#define SSI1_ADATA		0xB1680024
+#define SSI1_CLKDIV		0xB1680028
+#define SSI1_ENABLE		0xB1680100
 
 /*
  * Register content definitions
  */
-#define SSI_STATUS_BF				(1<<4)
-#define SSI_STATUS_OF				(1<<3)
-#define SSI_STATUS_UF				(1<<2)
-#define SSI_STATUS_D				(1<<1)
-#define SSI_STATUS_B				(1<<0)
+#define SSI_STATUS_BF		(1 << 4)
+#define SSI_STATUS_OF		(1 << 3)
+#define SSI_STATUS_UF		(1 << 2)
+#define SSI_STATUS_D		(1 << 1)
+#define SSI_STATUS_B		(1 << 0)
 
 /* SSI_INT */
-#define SSI_INT_OI					(1<<3)
-#define SSI_INT_UI					(1<<2)
-#define SSI_INT_DI					(1<<1)
+#define SSI_INT_OI		(1 << 3)
+#define SSI_INT_UI		(1 << 2)
+#define SSI_INT_DI		(1 << 1)
 
 /* SSI_INTEN */
-#define SSI_INTEN_OIE				(1<<3)
-#define SSI_INTEN_UIE				(1<<2)
-#define SSI_INTEN_DIE				(1<<1)
+#define SSI_INTEN_OIE		(1 << 3)
+#define SSI_INTEN_UIE		(1 << 2)
+#define SSI_INTEN_DIE		(1 << 1)
 
-#define SSI_CONFIG_AO				(1<<24)
-#define SSI_CONFIG_DO				(1<<23)
-#define SSI_CONFIG_ALEN				(7<<20)
-#define SSI_CONFIG_DLEN				(15<<16)
-#define SSI_CONFIG_DD				(1<<11)
-#define SSI_CONFIG_AD				(1<<10)
-#define SSI_CONFIG_BM				(3<<8)
-#define SSI_CONFIG_CE				(1<<7)
-#define SSI_CONFIG_DP				(1<<6)
-#define SSI_CONFIG_DL				(1<<5)
-#define SSI_CONFIG_EP				(1<<4)
-#define SSI_CONFIG_ALEN_N(N)		((N-1)<<20)
-#define SSI_CONFIG_DLEN_N(N)		((N-1)<<16)
-#define SSI_CONFIG_BM_HI			(0<<8)
-#define SSI_CONFIG_BM_LO			(1<<8)
-#define SSI_CONFIG_BM_CY			(2<<8)
+#define SSI_CONFIG_AO		(1 << 24)
+#define SSI_CONFIG_DO		(1 << 23)
+#define SSI_CONFIG_ALEN 	(7 << 20)
+#define SSI_CONFIG_DLEN 	(15 << 16)
+#define SSI_CONFIG_DD		(1 << 11)
+#define SSI_CONFIG_AD		(1 << 10)
+#define SSI_CONFIG_BM		(3 << 8)
+#define SSI_CONFIG_CE		(1 << 7)
+#define SSI_CONFIG_DP		(1 << 6)
+#define SSI_CONFIG_DL		(1 << 5)
+#define SSI_CONFIG_EP		(1 << 4)
+#define SSI_CONFIG_ALEN_N(N)	((N-1) << 20)
+#define SSI_CONFIG_DLEN_N(N)	((N-1) << 16)
+#define SSI_CONFIG_BM_HI	(0 << 8)
+#define SSI_CONFIG_BM_LO	(1 << 8)
+#define SSI_CONFIG_BM_CY	(2 << 8)
 
-#define SSI_ADATA_D					(1<<24)
-#define SSI_ADATA_ADDR				(0xFF<<16)
-#define SSI_ADATA_DATA				(0x0FFF)
-#define SSI_ADATA_ADDR_N(N)			(N<<16)
+#define SSI_ADATA_D		(1 << 24)
+#define SSI_ADATA_ADDR		(0xFF << 16)
+#define SSI_ADATA_DATA		0x0FFF
+#define SSI_ADATA_ADDR_N(N)	(N << 16)
 
-#define SSI_ENABLE_CD				(1<<1)
-#define SSI_ENABLE_E				(1<<0)
-
+#define SSI_ENABLE_CD		(1 << 1)
+#define SSI_ENABLE_E		(1 << 0)
 
 /* IrDA Controller */
-#define IRDA_BASE                 0xB0300000
-#define IR_RING_PTR_STATUS        (IRDA_BASE+0x00)
-#define IR_RING_BASE_ADDR_H       (IRDA_BASE+0x04)
-#define IR_RING_BASE_ADDR_L       (IRDA_BASE+0x08)
-#define IR_RING_SIZE              (IRDA_BASE+0x0C)
-#define IR_RING_PROMPT            (IRDA_BASE+0x10)
-#define IR_RING_ADDR_CMPR         (IRDA_BASE+0x14)
-#define IR_INT_CLEAR              (IRDA_BASE+0x18)
-#define IR_CONFIG_1               (IRDA_BASE+0x20)
-#  define IR_RX_INVERT_LED        (1<<0)
-#  define IR_TX_INVERT_LED        (1<<1)
-#  define IR_ST                   (1<<2)
-#  define IR_SF                   (1<<3)
-#  define IR_SIR                  (1<<4)
-#  define IR_MIR                  (1<<5)
-#  define IR_FIR                  (1<<6)
-#  define IR_16CRC                (1<<7)
-#  define IR_TD                   (1<<8)
-#  define IR_RX_ALL               (1<<9)
-#  define IR_DMA_ENABLE           (1<<10)
-#  define IR_RX_ENABLE            (1<<11)
-#  define IR_TX_ENABLE            (1<<12)
-#  define IR_LOOPBACK             (1<<14)
-#  define IR_SIR_MODE	          (IR_SIR | IR_DMA_ENABLE | \
-		                   IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
-#define IR_SIR_FLAGS              (IRDA_BASE+0x24)
-#define IR_ENABLE                 (IRDA_BASE+0x28)
-#  define IR_RX_STATUS            (1<<9)
-#  define IR_TX_STATUS            (1<<10)
-#define IR_READ_PHY_CONFIG        (IRDA_BASE+0x2C)
-#define IR_WRITE_PHY_CONFIG       (IRDA_BASE+0x30)
-#define IR_MAX_PKT_LEN            (IRDA_BASE+0x34)
-#define IR_RX_BYTE_CNT            (IRDA_BASE+0x38)
-#define IR_CONFIG_2               (IRDA_BASE+0x3C)
-#  define IR_MODE_INV             (1<<0)
-#  define IR_ONE_PIN              (1<<1)
-#define IR_INTERFACE_CONFIG       (IRDA_BASE+0x40)
+#define IRDA_BASE		0xB0300000
+#define IR_RING_PTR_STATUS	(IRDA_BASE + 0x00)
+#define IR_RING_BASE_ADDR_H	(IRDA_BASE + 0x04)
+#define IR_RING_BASE_ADDR_L	(IRDA_BASE + 0x08)
+#define IR_RING_SIZE		(IRDA_BASE + 0x0C)
+#define IR_RING_PROMPT		(IRDA_BASE + 0x10)
+#define IR_RING_ADDR_CMPR	(IRDA_BASE + 0x14)
+#define IR_INT_CLEAR		(IRDA_BASE + 0x18)
+#define IR_CONFIG_1		(IRDA_BASE + 0x20)
+#  define IR_RX_INVERT_LED	(1 << 0)
+#  define IR_TX_INVERT_LED	(1 << 1)
+#  define IR_ST 		(1 << 2)
+#  define IR_SF 		(1 << 3)
+#  define IR_SIR		(1 << 4)
+#  define IR_MIR		(1 << 5)
+#  define IR_FIR		(1 << 6)
+#  define IR_16CRC		(1 << 7)
+#  define IR_TD 		(1 << 8)
+#  define IR_RX_ALL		(1 << 9)
+#  define IR_DMA_ENABLE 	(1 << 10)
+#  define IR_RX_ENABLE		(1 << 11)
+#  define IR_TX_ENABLE		(1 << 12)
+#  define IR_LOOPBACK		(1 << 14)
+#  define IR_SIR_MODE		(IR_SIR | IR_DMA_ENABLE | \
+				 IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
+#define IR_SIR_FLAGS		(IRDA_BASE + 0x24)
+#define IR_ENABLE		(IRDA_BASE + 0x28)
+#  define IR_RX_STATUS		(1 << 9)
+#  define IR_TX_STATUS		(1 << 10)
+#define IR_READ_PHY_CONFIG	(IRDA_BASE + 0x2C)
+#define IR_WRITE_PHY_CONFIG	(IRDA_BASE + 0x30)
+#define IR_MAX_PKT_LEN		(IRDA_BASE + 0x34)
+#define IR_RX_BYTE_CNT		(IRDA_BASE + 0x38)
+#define IR_CONFIG_2		(IRDA_BASE + 0x3C)
+#  define IR_MODE_INV		(1 << 0)
+#  define IR_ONE_PIN		(1 << 1)
+#define IR_INTERFACE_CONFIG	(IRDA_BASE + 0x40)
 
 /* GPIO */
-#define SYS_PINFUNC               0xB190002C
-#  define SYS_PF_USB			(1<<15)	/* 2nd USB device/host */
-#  define SYS_PF_U3			(1<<14)	/* GPIO23/U3TXD */
-#  define SYS_PF_U2			(1<<13) /* GPIO22/U2TXD */
-#  define SYS_PF_U1			(1<<12) /* GPIO21/U1TXD */
-#  define SYS_PF_SRC			(1<<11)	/* GPIO6/SROMCKE */
-#  define SYS_PF_CK5			(1<<10)	/* GPIO3/CLK5 */
-#  define SYS_PF_CK4			(1<<9)	/* GPIO2/CLK4 */
-#  define SYS_PF_IRF			(1<<8)	/* GPIO15/IRFIRSEL */
-#  define SYS_PF_UR3			(1<<7)	/* GPIO[14:9]/UART3 */
-#  define SYS_PF_I2D			(1<<6)	/* GPIO8/I2SDI */
-#  define SYS_PF_I2S			(1<<5)	/* I2S/GPIO[29:31] */
-#  define SYS_PF_NI2			(1<<4)	/* NI2/GPIO[24:28] */
-#  define SYS_PF_U0			(1<<3)	/* U0TXD/GPIO20 */
-#  define SYS_PF_RD			(1<<2)	/* IRTXD/GPIO19 */
-#  define SYS_PF_A97			(1<<1)	/* AC97/SSL1 */
-#  define SYS_PF_S0			(1<<0)	/* SSI_0/GPIO[16:18] */
+#define SYS_PINFUNC		0xB190002C
+#  define SYS_PF_USB		(1 << 15)	/* 2nd USB device/host */
+#  define SYS_PF_U3		(1 << 14)	/* GPIO23/U3TXD */
+#  define SYS_PF_U2		(1 << 13)	/* GPIO22/U2TXD */
+#  define SYS_PF_U1		(1 << 12)	/* GPIO21/U1TXD */
+#  define SYS_PF_SRC		(1 << 11)	/* GPIO6/SROMCKE */
+#  define SYS_PF_CK5		(1 << 10)	/* GPIO3/CLK5 */
+#  define SYS_PF_CK4		(1 << 9)	/* GPIO2/CLK4 */
+#  define SYS_PF_IRF		(1 << 8)	/* GPIO15/IRFIRSEL */
+#  define SYS_PF_UR3		(1 << 7)	/* GPIO[14:9]/UART3 */
+#  define SYS_PF_I2D		(1 << 6)	/* GPIO8/I2SDI */
+#  define SYS_PF_I2S		(1 << 5)	/* I2S/GPIO[29:31] */
+#  define SYS_PF_NI2		(1 << 4)	/* NI2/GPIO[24:28] */
+#  define SYS_PF_U0		(1 << 3)	/* U0TXD/GPIO20 */
+#  define SYS_PF_RD		(1 << 2)	/* IRTXD/GPIO19 */
+#  define SYS_PF_A97		(1 << 1)	/* AC97/SSL1 */
+#  define SYS_PF_S0		(1 << 0)	/* SSI_0/GPIO[16:18] */
 
-/* Au1100 Only */
-#  define SYS_PF_PC			(1<<18)	/* PCMCIA/GPIO[207:204] */
-#  define SYS_PF_LCD			(1<<17)	/* extern lcd/GPIO[203:200] */
-#  define SYS_PF_CS			(1<<16)	/* EXTCLK0/32khz to gpio2 */
-#  define SYS_PF_EX0			(1<<9)	/* gpio2/clock */
+/* Au1100 only */
+#  define SYS_PF_PC		(1 << 18)	/* PCMCIA/GPIO[207:204] */
+#  define SYS_PF_LCD		(1 << 17)	/* extern lcd/GPIO[203:200] */
+#  define SYS_PF_CS		(1 << 16)	/* EXTCLK0/32KHz to gpio2 */
+#  define SYS_PF_EX0		(1 << 9)	/* GPIO2/clock */
 
-/* Au1550 Only.  Redefines lots of pins */
-#  define SYS_PF_PSC2_MASK		(7 << 17)
-#  define SYS_PF_PSC2_AC97		(0)
-#  define SYS_PF_PSC2_SPI		(0)
-#  define SYS_PF_PSC2_I2S		(1 << 17)
-#  define SYS_PF_PSC2_SMBUS		(3 << 17)
-#  define SYS_PF_PSC2_GPIO		(7 << 17)
-#  define SYS_PF_PSC3_MASK		(7 << 20)
-#  define SYS_PF_PSC3_AC97		(0)
-#  define SYS_PF_PSC3_SPI		(0)
-#  define SYS_PF_PSC3_I2S		(1 << 20)
-#  define SYS_PF_PSC3_SMBUS		(3 << 20)
-#  define SYS_PF_PSC3_GPIO		(7 << 20)
-#  define SYS_PF_PSC1_S1		(1 << 1)
-#  define SYS_PF_MUST_BE_SET		((1 << 5) | (1 << 2))
+/* Au1550 only.  Redefines lots of pins */
+#  define SYS_PF_PSC2_MASK	(7 << 17)
+#  define SYS_PF_PSC2_AC97	0
+#  define SYS_PF_PSC2_SPI	0
+#  define SYS_PF_PSC2_I2S	(1 << 17)
+#  define SYS_PF_PSC2_SMBUS	(3 << 17)
+#  define SYS_PF_PSC2_GPIO	(7 << 17)
+#  define SYS_PF_PSC3_MASK	(7 << 20)
+#  define SYS_PF_PSC3_AC97	0
+#  define SYS_PF_PSC3_SPI	0
+#  define SYS_PF_PSC3_I2S	(1 << 20)
+#  define SYS_PF_PSC3_SMBUS	(3 << 20)
+#  define SYS_PF_PSC3_GPIO	(7 << 20)
+#  define SYS_PF_PSC1_S1	(1 << 1)
+#  define SYS_PF_MUST_BE_SET	((1 << 5) | (1 << 2))
 
-/* Au1200 Only */
+/* Au1200 only */
 #ifdef CONFIG_SOC_AU1200
-#define SYS_PINFUNC_DMA		(1<<31)
-#define SYS_PINFUNC_S0A		(1<<30)
-#define SYS_PINFUNC_S1A		(1<<29)
-#define SYS_PINFUNC_LP0		(1<<28)
-#define SYS_PINFUNC_LP1		(1<<27)
-#define SYS_PINFUNC_LD16	(1<<26)
-#define SYS_PINFUNC_LD8		(1<<25)
-#define SYS_PINFUNC_LD1		(1<<24)
-#define SYS_PINFUNC_LD0		(1<<23)
-#define SYS_PINFUNC_P1A		(3<<21)
-#define SYS_PINFUNC_P1B		(1<<20)
-#define SYS_PINFUNC_FS3		(1<<19)
-#define SYS_PINFUNC_P0A		(3<<17)
-#define SYS_PINFUNC_CS		(1<<16)
-#define SYS_PINFUNC_CIM		(1<<15)
-#define SYS_PINFUNC_P1C		(1<<14)
-#define SYS_PINFUNC_U1T		(1<<12)
-#define SYS_PINFUNC_U1R		(1<<11)
-#define SYS_PINFUNC_EX1		(1<<10)
-#define SYS_PINFUNC_EX0		(1<<9)
-#define SYS_PINFUNC_U0R		(1<<8)
-#define SYS_PINFUNC_MC		(1<<7)
-#define SYS_PINFUNC_S0B		(1<<6)
-#define SYS_PINFUNC_S0C		(1<<5)
-#define SYS_PINFUNC_P0B		(1<<4)
-#define SYS_PINFUNC_U0T		(1<<3)
-#define SYS_PINFUNC_S1B		(1<<2)
+#define SYS_PINFUNC_DMA 	(1 << 31)
+#define SYS_PINFUNC_S0A 	(1 << 30)
+#define SYS_PINFUNC_S1A 	(1 << 29)
+#define SYS_PINFUNC_LP0 	(1 << 28)
+#define SYS_PINFUNC_LP1 	(1 << 27)
+#define SYS_PINFUNC_LD16 	(1 << 26)
+#define SYS_PINFUNC_LD8 	(1 << 25)
+#define SYS_PINFUNC_LD1 	(1 << 24)
+#define SYS_PINFUNC_LD0 	(1 << 23)
+#define SYS_PINFUNC_P1A 	(3 << 21)
+#define SYS_PINFUNC_P1B 	(1 << 20)
+#define SYS_PINFUNC_FS3 	(1 << 19)
+#define SYS_PINFUNC_P0A 	(3 << 17)
+#define SYS_PINFUNC_CS		(1 << 16)
+#define SYS_PINFUNC_CIM 	(1 << 15)
+#define SYS_PINFUNC_P1C 	(1 << 14)
+#define SYS_PINFUNC_U1T 	(1 << 12)
+#define SYS_PINFUNC_U1R 	(1 << 11)
+#define SYS_PINFUNC_EX1 	(1 << 10)
+#define SYS_PINFUNC_EX0 	(1 << 9)
+#define SYS_PINFUNC_U0R 	(1 << 8)
+#define SYS_PINFUNC_MC		(1 << 7)
+#define SYS_PINFUNC_S0B 	(1 << 6)
+#define SYS_PINFUNC_S0C 	(1 << 5)
+#define SYS_PINFUNC_P0B 	(1 << 4)
+#define SYS_PINFUNC_U0T 	(1 << 3)
+#define SYS_PINFUNC_S1B 	(1 << 2)
 #endif
 
-#define SYS_TRIOUTRD              0xB1900100
-#define SYS_TRIOUTCLR             0xB1900100
-#define SYS_OUTPUTRD              0xB1900108
-#define SYS_OUTPUTSET             0xB1900108
-#define SYS_OUTPUTCLR             0xB190010C
-#define SYS_PINSTATERD            0xB1900110
-#define SYS_PININPUTEN            0xB1900110
+#define SYS_TRIOUTRD		0xB1900100
+#define SYS_TRIOUTCLR		0xB1900100
+#define SYS_OUTPUTRD		0xB1900108
+#define SYS_OUTPUTSET		0xB1900108
+#define SYS_OUTPUTCLR		0xB190010C
+#define SYS_PINSTATERD		0xB1900110
+#define SYS_PININPUTEN		0xB1900110
 
 /* GPIO2, Au1500, Au1550 only */
-#define GPIO2_BASE                0xB1700000
-#define GPIO2_DIR                 (GPIO2_BASE + 0)
-#define GPIO2_OUTPUT              (GPIO2_BASE + 8)
-#define GPIO2_PINSTATE            (GPIO2_BASE + 0xC)
-#define GPIO2_INTENABLE           (GPIO2_BASE + 0x10)
-#define GPIO2_ENABLE              (GPIO2_BASE + 0x14)
+#define GPIO2_BASE		0xB1700000
+#define GPIO2_DIR		(GPIO2_BASE + 0)
+#define GPIO2_OUTPUT		(GPIO2_BASE + 8)
+#define GPIO2_PINSTATE		(GPIO2_BASE + 0xC)
+#define GPIO2_INTENABLE 	(GPIO2_BASE + 0x10)
+#define GPIO2_ENABLE		(GPIO2_BASE + 0x14)
 
 /* Power Management */
-#define SYS_SCRATCH0              0xB1900018
-#define SYS_SCRATCH1              0xB190001C
-#define SYS_WAKEMSK               0xB1900034
-#define SYS_ENDIAN                0xB1900038
-#define SYS_POWERCTRL             0xB190003C
-#define SYS_WAKESRC               0xB190005C
-#define SYS_SLPPWR                0xB1900078
-#define SYS_SLEEP                 0xB190007C
+#define SYS_SCRATCH0		0xB1900018
+#define SYS_SCRATCH1		0xB190001C
+#define SYS_WAKEMSK		0xB1900034
+#define SYS_ENDIAN		0xB1900038
+#define SYS_POWERCTRL		0xB190003C
+#define SYS_WAKESRC		0xB190005C
+#define SYS_SLPPWR		0xB1900078
+#define SYS_SLEEP		0xB190007C
 
 /* Clock Controller */
-#define SYS_FREQCTRL0             0xB1900020
-#  define SYS_FC_FRDIV2_BIT         22
-#  define SYS_FC_FRDIV2_MASK        (0xff << SYS_FC_FRDIV2_BIT)
-#  define SYS_FC_FE2                (1<<21)
-#  define SYS_FC_FS2                (1<<20)
-#  define SYS_FC_FRDIV1_BIT         12
-#  define SYS_FC_FRDIV1_MASK        (0xff << SYS_FC_FRDIV1_BIT)
-#  define SYS_FC_FE1                (1<<11)
-#  define SYS_FC_FS1                (1<<10)
-#  define SYS_FC_FRDIV0_BIT         2
-#  define SYS_FC_FRDIV0_MASK        (0xff << SYS_FC_FRDIV0_BIT)
-#  define SYS_FC_FE0                (1<<1)
-#  define SYS_FC_FS0                (1<<0)
-#define SYS_FREQCTRL1             0xB1900024
-#  define SYS_FC_FRDIV5_BIT         22
-#  define SYS_FC_FRDIV5_MASK        (0xff << SYS_FC_FRDIV5_BIT)
-#  define SYS_FC_FE5                (1<<21)
-#  define SYS_FC_FS5                (1<<20)
-#  define SYS_FC_FRDIV4_BIT         12
-#  define SYS_FC_FRDIV4_MASK        (0xff << SYS_FC_FRDIV4_BIT)
-#  define SYS_FC_FE4                (1<<11)
-#  define SYS_FC_FS4                (1<<10)
-#  define SYS_FC_FRDIV3_BIT         2
-#  define SYS_FC_FRDIV3_MASK        (0xff << SYS_FC_FRDIV3_BIT)
-#  define SYS_FC_FE3                (1<<1)
-#  define SYS_FC_FS3                (1<<0)
-#define SYS_CLKSRC                0xB1900028
-#  define SYS_CS_ME1_BIT            27
-#  define SYS_CS_ME1_MASK           (0x7<<SYS_CS_ME1_BIT)
-#  define SYS_CS_DE1                (1<<26)
-#  define SYS_CS_CE1                (1<<25)
-#  define SYS_CS_ME0_BIT            22
-#  define SYS_CS_ME0_MASK           (0x7<<SYS_CS_ME0_BIT)
-#  define SYS_CS_DE0                (1<<21)
-#  define SYS_CS_CE0                (1<<20)
-#  define SYS_CS_MI2_BIT            17
-#  define SYS_CS_MI2_MASK           (0x7<<SYS_CS_MI2_BIT)
-#  define SYS_CS_DI2                (1<<16)
-#  define SYS_CS_CI2                (1<<15)
+#define SYS_FREQCTRL0		0xB1900020
+#  define SYS_FC_FRDIV2_BIT	22
+#  define SYS_FC_FRDIV2_MASK	(0xff << SYS_FC_FRDIV2_BIT)
+#  define SYS_FC_FE2		(1 << 21)
+#  define SYS_FC_FS2		(1 << 20)
+#  define SYS_FC_FRDIV1_BIT	12
+#  define SYS_FC_FRDIV1_MASK	(0xff << SYS_FC_FRDIV1_BIT)
+#  define SYS_FC_FE1		(1 << 11)
+#  define SYS_FC_FS1		(1 << 10)
+#  define SYS_FC_FRDIV0_BIT	2
+#  define SYS_FC_FRDIV0_MASK	(0xff << SYS_FC_FRDIV0_BIT)
+#  define SYS_FC_FE0		(1 << 1)
+#  define SYS_FC_FS0		(1 << 0)
+#define SYS_FREQCTRL1		0xB1900024
+#  define SYS_FC_FRDIV5_BIT	22
+#  define SYS_FC_FRDIV5_MASK	(0xff << SYS_FC_FRDIV5_BIT)
+#  define SYS_FC_FE5		(1 << 21)
+#  define SYS_FC_FS5		(1 << 20)
+#  define SYS_FC_FRDIV4_BIT	12
+#  define SYS_FC_FRDIV4_MASK	(0xff << SYS_FC_FRDIV4_BIT)
+#  define SYS_FC_FE4		(1 << 11)
+#  define SYS_FC_FS4		(1 << 10)
+#  define SYS_FC_FRDIV3_BIT	2
+#  define SYS_FC_FRDIV3_MASK	(0xff << SYS_FC_FRDIV3_BIT)
+#  define SYS_FC_FE3		(1 << 1)
+#  define SYS_FC_FS3		(1 << 0)
+#define SYS_CLKSRC		0xB1900028
+#  define SYS_CS_ME1_BIT	27
+#  define SYS_CS_ME1_MASK	(0x7 << SYS_CS_ME1_BIT)
+#  define SYS_CS_DE1		(1 << 26)
+#  define SYS_CS_CE1		(1 << 25)
+#  define SYS_CS_ME0_BIT	22
+#  define SYS_CS_ME0_MASK	(0x7 << SYS_CS_ME0_BIT)
+#  define SYS_CS_DE0		(1 << 21)
+#  define SYS_CS_CE0		(1 << 20)
+#  define SYS_CS_MI2_BIT	17
+#  define SYS_CS_MI2_MASK	(0x7 << SYS_CS_MI2_BIT)
+#  define SYS_CS_DI2		(1 << 16)
+#  define SYS_CS_CI2		(1 << 15)
 #ifdef CONFIG_SOC_AU1100
-#  define SYS_CS_ML_BIT             7
-#  define SYS_CS_ML_MASK            (0x7<<SYS_CS_ML_BIT)
-#  define SYS_CS_DL                 (1<<6)
-#  define SYS_CS_CL                 (1<<5)
+#  define SYS_CS_ML_BIT 	7
+#  define SYS_CS_ML_MASK	(0x7 << SYS_CS_ML_BIT)
+#  define SYS_CS_DL		(1 << 6)
+#  define SYS_CS_CL		(1 << 5)
 #else
-#  define SYS_CS_MUH_BIT            12
-#  define SYS_CS_MUH_MASK           (0x7<<SYS_CS_MUH_BIT)
-#  define SYS_CS_DUH                (1<<11)
-#  define SYS_CS_CUH                (1<<10)
-#  define SYS_CS_MUD_BIT            7
-#  define SYS_CS_MUD_MASK           (0x7<<SYS_CS_MUD_BIT)
-#  define SYS_CS_DUD                (1<<6)
-#  define SYS_CS_CUD                (1<<5)
+#  define SYS_CS_MUH_BIT	12
+#  define SYS_CS_MUH_MASK	(0x7 << SYS_CS_MUH_BIT)
+#  define SYS_CS_DUH		(1 << 11)
+#  define SYS_CS_CUH		(1 << 10)
+#  define SYS_CS_MUD_BIT	7
+#  define SYS_CS_MUD_MASK	(0x7 << SYS_CS_MUD_BIT)
+#  define SYS_CS_DUD		(1 << 6)
+#  define SYS_CS_CUD		(1 << 5)
 #endif
-#  define SYS_CS_MIR_BIT            2
-#  define SYS_CS_MIR_MASK           (0x7<<SYS_CS_MIR_BIT)
-#  define SYS_CS_DIR                (1<<1)
-#  define SYS_CS_CIR                (1<<0)
+#  define SYS_CS_MIR_BIT	2
+#  define SYS_CS_MIR_MASK	(0x7 << SYS_CS_MIR_BIT)
+#  define SYS_CS_DIR		(1 << 1)
+#  define SYS_CS_CIR		(1 << 0)
 
-#  define SYS_CS_MUX_AUX            0x1
-#  define SYS_CS_MUX_FQ0            0x2
-#  define SYS_CS_MUX_FQ1            0x3
-#  define SYS_CS_MUX_FQ2            0x4
-#  define SYS_CS_MUX_FQ3            0x5
-#  define SYS_CS_MUX_FQ4            0x6
-#  define SYS_CS_MUX_FQ5            0x7
-#define SYS_CPUPLL                0xB1900060
-#define SYS_AUXPLL                0xB1900064
+#  define SYS_CS_MUX_AUX	0x1
+#  define SYS_CS_MUX_FQ0	0x2
+#  define SYS_CS_MUX_FQ1	0x3
+#  define SYS_CS_MUX_FQ2	0x4
+#  define SYS_CS_MUX_FQ3	0x5
+#  define SYS_CS_MUX_FQ4	0x6
+#  define SYS_CS_MUX_FQ5	0x7
+#define SYS_CPUPLL		0xB1900060
+#define SYS_AUXPLL		0xB1900064
 
 /* AC97 Controller */
-#define AC97C_CONFIG              0xB0000000
-#  define AC97C_RECV_SLOTS_BIT  13
+#define AC97C_CONFIG		0xB0000000
+#  define AC97C_RECV_SLOTS_BIT	13
 #  define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT)
-#  define AC97C_XMIT_SLOTS_BIT  3
+#  define AC97C_XMIT_SLOTS_BIT	3
 #  define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT)
-#  define AC97C_SG              (1<<2)
-#  define AC97C_SYNC            (1<<1)
-#  define AC97C_RESET           (1<<0)
-#define AC97C_STATUS              0xB0000004
-#  define AC97C_XU              (1<<11)
-#  define AC97C_XO              (1<<10)
-#  define AC97C_RU              (1<<9)
-#  define AC97C_RO              (1<<8)
-#  define AC97C_READY           (1<<7)
-#  define AC97C_CP              (1<<6)
-#  define AC97C_TR              (1<<5)
-#  define AC97C_TE              (1<<4)
-#  define AC97C_TF              (1<<3)
-#  define AC97C_RR              (1<<2)
-#  define AC97C_RE              (1<<1)
-#  define AC97C_RF              (1<<0)
-#define AC97C_DATA                0xB0000008
-#define AC97C_CMD                 0xB000000C
-#  define AC97C_WD_BIT          16
-#  define AC97C_READ            (1<<7)
-#  define AC97C_INDEX_MASK      0x7f
-#define AC97C_CNTRL               0xB0000010
-#  define AC97C_RS              (1<<1)
-#  define AC97C_CE              (1<<0)
-
+#  define AC97C_SG		(1 << 2)
+#  define AC97C_SYNC		(1 << 1)
+#  define AC97C_RESET		(1 << 0)
+#define AC97C_STATUS		0xB0000004
+#  define AC97C_XU		(1 << 11)
+#  define AC97C_XO		(1 << 10)
+#  define AC97C_RU		(1 << 9)
+#  define AC97C_RO		(1 << 8)
+#  define AC97C_READY		(1 << 7)
+#  define AC97C_CP		(1 << 6)
+#  define AC97C_TR		(1 << 5)
+#  define AC97C_TE		(1 << 4)
+#  define AC97C_TF		(1 << 3)
+#  define AC97C_RR		(1 << 2)
+#  define AC97C_RE		(1 << 1)
+#  define AC97C_RF		(1 << 0)
+#define AC97C_DATA		0xB0000008
+#define AC97C_CMD		0xB000000C
+#  define AC97C_WD_BIT		16
+#  define AC97C_READ		(1 << 7)
+#  define AC97C_INDEX_MASK	0x7f
+#define AC97C_CNTRL		0xB0000010
+#  define AC97C_RS		(1 << 1)
+#  define AC97C_CE		(1 << 0)
 
 /* Secure Digital (SD) Controller */
 #define SD0_XMIT_FIFO	0xB0600000
@@ -1638,73 +1633,74 @@
 
 #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
 /* Au1500 PCI Controller */
-#define Au1500_CFG_BASE           0xB4005000 // virtual, kseg0 addr
-#define Au1500_PCI_CMEM           (Au1500_CFG_BASE + 0)
-#define Au1500_PCI_CFG            (Au1500_CFG_BASE + 4)
-#  define PCI_ERROR ((1<<22) | (1<<23) | (1<<24) | (1<<25) | (1<<26) | (1<<27))
-#define Au1500_PCI_B2BMASK_CCH    (Au1500_CFG_BASE + 8)
-#define Au1500_PCI_B2B0_VID       (Au1500_CFG_BASE + 0xC)
-#define Au1500_PCI_B2B1_ID        (Au1500_CFG_BASE + 0x10)
-#define Au1500_PCI_MWMASK_DEV     (Au1500_CFG_BASE + 0x14)
+#define Au1500_CFG_BASE 	0xB4005000	/* virtual, KSEG1 addr */
+#define Au1500_PCI_CMEM 	(Au1500_CFG_BASE + 0)
+#define Au1500_PCI_CFG		(Au1500_CFG_BASE + 4)
+#  define PCI_ERROR		((1 << 22) | (1 << 23) | (1 << 24) | \
+				 (1 << 25) | (1 << 26) | (1 << 27))
+#define Au1500_PCI_B2BMASK_CCH	(Au1500_CFG_BASE + 8)
+#define Au1500_PCI_B2B0_VID	(Au1500_CFG_BASE + 0xC)
+#define Au1500_PCI_B2B1_ID	(Au1500_CFG_BASE + 0x10)
+#define Au1500_PCI_MWMASK_DEV	(Au1500_CFG_BASE + 0x14)
 #define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18)
-#define Au1500_PCI_ERR_ADDR       (Au1500_CFG_BASE + 0x1C)
-#define Au1500_PCI_SPEC_INTACK    (Au1500_CFG_BASE + 0x20)
-#define Au1500_PCI_ID             (Au1500_CFG_BASE + 0x100)
-#define Au1500_PCI_STATCMD        (Au1500_CFG_BASE + 0x104)
-#define Au1500_PCI_CLASSREV       (Au1500_CFG_BASE + 0x108)
-#define Au1500_PCI_HDRTYPE        (Au1500_CFG_BASE + 0x10C)
-#define Au1500_PCI_MBAR           (Au1500_CFG_BASE + 0x110)
+#define Au1500_PCI_ERR_ADDR	(Au1500_CFG_BASE + 0x1C)
+#define Au1500_PCI_SPEC_INTACK	(Au1500_CFG_BASE + 0x20)
+#define Au1500_PCI_ID		(Au1500_CFG_BASE + 0x100)
+#define Au1500_PCI_STATCMD	(Au1500_CFG_BASE + 0x104)
+#define Au1500_PCI_CLASSREV	(Au1500_CFG_BASE + 0x108)
+#define Au1500_PCI_HDRTYPE	(Au1500_CFG_BASE + 0x10C)
+#define Au1500_PCI_MBAR 	(Au1500_CFG_BASE + 0x110)
 
-#define Au1500_PCI_HDR            0xB4005100 // virtual, kseg0 addr
+#define Au1500_PCI_HDR		0xB4005100	/* virtual, KSEG1 addr */
 
-/* All of our structures, like pci resource, have 32 bit members.
+/*
+ * All of our structures, like PCI resource, have 32-bit members.
  * Drivers are expected to do an ioremap on the PCI MEM resource, but it's
- * hard to store 0x4 0000 0000 in a 32 bit type.  We require a small patch
+ * hard to store 0x4 0000 0000 in a 32-bit type.  We require a small patch
  * to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and
- * (u32)Au1500_PCI_MEM_END and change those to the full 36 bit PCI MEM
- * addresses.  For PCI IO, it's simpler because we get to do the ioremap
+ * (u32)Au1500_PCI_MEM_END and change those to the full 36-bit PCI MEM
+ * addresses.  For PCI I/O, it's simpler because we get to do the ioremap
  * ourselves and then adjust the device's resources.
  */
-#define Au1500_EXT_CFG            0x600000000ULL
-#define Au1500_EXT_CFG_TYPE1      0x680000000ULL
-#define Au1500_PCI_IO_START       0x500000000ULL
-#define Au1500_PCI_IO_END         0x5000FFFFFULL
-#define Au1500_PCI_MEM_START      0x440000000ULL
-#define Au1500_PCI_MEM_END        0x44FFFFFFFULL
+#define Au1500_EXT_CFG		0x600000000ULL
+#define Au1500_EXT_CFG_TYPE1	0x680000000ULL
+#define Au1500_PCI_IO_START	0x500000000ULL
+#define Au1500_PCI_IO_END	0x5000FFFFFULL
+#define Au1500_PCI_MEM_START	0x440000000ULL
+#define Au1500_PCI_MEM_END	0x44FFFFFFFULL
 
 #define PCI_IO_START	0x00001000
 #define PCI_IO_END	0x000FFFFF
 #define PCI_MEM_START	0x40000000
 #define PCI_MEM_END	0x4FFFFFFF
 
-#define PCI_FIRST_DEVFN (0<<3)
-#define PCI_LAST_DEVFN  (19<<3)
+#define PCI_FIRST_DEVFN (0 << 3)
+#define PCI_LAST_DEVFN	(19 << 3)
 
-#define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */
-#define IOPORT_RESOURCE_END   0xffffffff
-#define IOMEM_RESOURCE_START  0x10000000
-#define IOMEM_RESOURCE_END    0xffffffff
+#define IOPORT_RESOURCE_START	0x00001000	/* skip legacy probing */
+#define IOPORT_RESOURCE_END	0xffffffff
+#define IOMEM_RESOURCE_START	0x10000000
+#define IOMEM_RESOURCE_END	0xffffffff
 
 #else /* Au1000 and Au1100 and Au1200 */
 
-/* don't allow any legacy ports probing */
-#define IOPORT_RESOURCE_START 0x10000000
-#define IOPORT_RESOURCE_END   0xffffffff
-#define IOMEM_RESOURCE_START  0x10000000
-#define IOMEM_RESOURCE_END    0xffffffff
+/* Don't allow any legacy ports probing */
+#define IOPORT_RESOURCE_START	0x10000000
+#define IOPORT_RESOURCE_END	0xffffffff
+#define IOMEM_RESOURCE_START	0x10000000
+#define IOMEM_RESOURCE_END	0xffffffff
 
-#define PCI_IO_START    0
-#define PCI_IO_END      0
-#define PCI_MEM_START   0
-#define PCI_MEM_END     0
+#define PCI_IO_START	0
+#define PCI_IO_END	0
+#define PCI_MEM_START	0
+#define PCI_MEM_END	0
 #define PCI_FIRST_DEVFN 0
-#define PCI_LAST_DEVFN  0
+#define PCI_LAST_DEVFN	0
 
 #endif
 
 #ifndef _LANGUAGE_ASSEMBLY
-typedef volatile struct
-{
+typedef volatile struct {
 	/* 0x0000 */ u32 toytrim;
 	/* 0x0004 */ u32 toywrite;
 	/* 0x0008 */ u32 toymatch0;
@@ -1746,13 +1742,14 @@
 	/* 0x010C */ u32 outputclr;
 	/* 0x0110 */ u32 pinstaterd;
 #define pininputen pinstaterd
-
 } AU1X00_SYS;
 
-static AU1X00_SYS* const sys  = (AU1X00_SYS *)SYS_BASE;
+static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE;
 
 #endif
-/* Processor information base on prid.
+
+/*
+ * Processor information based on PRID.
  * Copied from PowerPC.
  */
 #ifndef _LANGUAGE_ASSEMBLY
@@ -1767,9 +1764,8 @@
 	unsigned char	cpu_pll_wo;	/* sys_cpupll reg. write-only */
 };
 
-extern struct cpu_spec		cpu_specs[];
-extern struct cpu_spec		*cur_cpu_spec[];
+extern struct cpu_spec	cpu_specs[];
+extern struct cpu_spec	*cur_cpu_spec[];
 #endif
 
 #endif
-
diff --git a/include/asm-mips/mach-au1x00/au1000_dma.h b/include/asm-mips/mach-au1x00/au1000_dma.h
index 9f29520..c333b4e 100644
--- a/include/asm-mips/mach-au1x00/au1000_dma.h
+++ b/include/asm-mips/mach-au1x00/au1000_dma.h
@@ -1,11 +1,10 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Defines for using and allocating dma channels on the Alchemy
- *      Au1000 mips processor.
+ *	Defines for using and allocating DMA channels on the Alchemy
+ *      Au1x00 MIPS processors.
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	stevel@mvista.com or source@mvista.com
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.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
@@ -31,7 +30,7 @@
 #ifndef __ASM_AU1000_DMA_H
 #define __ASM_AU1000_DMA_H
 
-#include <asm/io.h>		/* need byte IO */
+#include <linux/io.h>		/* need byte IO */
 #include <linux/spinlock.h>	/* And spinlocks */
 #include <linux/delay.h>
 #include <asm/system.h>
@@ -50,36 +49,36 @@
 #define DMA_DAH_MASK		(0x0f << 20)
 #define DMA_DID_BIT		16
 #define DMA_DID_MASK		(0x0f << DMA_DID_BIT)
-#define DMA_DS			(1<<15)
-#define DMA_BE			(1<<13)
-#define DMA_DR			(1<<12)
-#define DMA_TS8			(1<<11)
+#define DMA_DS			(1 << 15)
+#define DMA_BE			(1 << 13)
+#define DMA_DR			(1 << 12)
+#define DMA_TS8 		(1 << 11)
 #define DMA_DW_BIT		9
 #define DMA_DW_MASK		(0x03 << DMA_DW_BIT)
 #define DMA_DW8			(0 << DMA_DW_BIT)
 #define DMA_DW16		(1 << DMA_DW_BIT)
 #define DMA_DW32		(2 << DMA_DW_BIT)
-#define DMA_NC			(1<<8)
-#define DMA_IE			(1<<7)
-#define DMA_HALT		(1<<6)
-#define DMA_GO			(1<<5)
-#define DMA_AB			(1<<4)
-#define DMA_D1			(1<<3)
-#define DMA_BE1			(1<<2)
-#define DMA_D0			(1<<1)
-#define DMA_BE0			(1<<0)
+#define DMA_NC			(1 << 8)
+#define DMA_IE			(1 << 7)
+#define DMA_HALT		(1 << 6)
+#define DMA_GO			(1 << 5)
+#define DMA_AB			(1 << 4)
+#define DMA_D1			(1 << 3)
+#define DMA_BE1 		(1 << 2)
+#define DMA_D0			(1 << 1)
+#define DMA_BE0 		(1 << 0)
 
-#define DMA_PERIPHERAL_ADDR       0x00000008
-#define DMA_BUFFER0_START         0x0000000C
-#define DMA_BUFFER1_START         0x00000014
-#define DMA_BUFFER0_COUNT         0x00000010
-#define DMA_BUFFER1_COUNT         0x00000018
-#define DMA_BAH_BIT 16
-#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT)
-#define DMA_COUNT_BIT 0
-#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT)
+#define DMA_PERIPHERAL_ADDR	0x00000008
+#define DMA_BUFFER0_START	0x0000000C
+#define DMA_BUFFER1_START	0x00000014
+#define DMA_BUFFER0_COUNT	0x00000010
+#define DMA_BUFFER1_COUNT	0x00000018
+#define DMA_BAH_BIT	16
+#define DMA_BAH_MASK	(0x0f << DMA_BAH_BIT)
+#define DMA_COUNT_BIT	0
+#define DMA_COUNT_MASK	(0xffff << DMA_COUNT_BIT)
 
-/* DMA Device ID's follow */
+/* DMA Device IDs follow */
 enum {
 	DMA_ID_UART0_TX = 0,
 	DMA_ID_UART0_RX,
@@ -110,7 +109,8 @@
 };
 
 struct dma_chan {
-	int dev_id;		// this channel is allocated if >=0, free otherwise
+	int dev_id;		/* this channel is allocated if >= 0, */
+				/* free otherwise */
 	unsigned int io;
 	const char *dev_str;
 	int irq;
@@ -132,23 +132,23 @@
 extern void dump_au1000_dma_channel(unsigned int dmanr);
 extern spinlock_t au1000_dma_spin_lock;
 
-
-static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr)
+static inline struct dma_chan *get_dma_chan(unsigned int dmanr)
 {
-	if (dmanr >= NUM_AU1000_DMA_CHANNELS
-	    || au1000_dma_table[dmanr].dev_id < 0)
+	if (dmanr >= NUM_AU1000_DMA_CHANNELS ||
+	    au1000_dma_table[dmanr].dev_id < 0)
 		return NULL;
 	return &au1000_dma_table[dmanr];
 }
 
-static __inline__ unsigned long claim_dma_lock(void)
+static inline unsigned long claim_dma_lock(void)
 {
 	unsigned long flags;
+
 	spin_lock_irqsave(&au1000_dma_spin_lock, flags);
 	return flags;
 }
 
-static __inline__ void release_dma_lock(unsigned long flags)
+static inline void release_dma_lock(unsigned long flags)
 {
 	spin_unlock_irqrestore(&au1000_dma_spin_lock, flags);
 }
@@ -156,48 +156,53 @@
 /*
  * Set the DMA buffer enable bits in the mode register.
  */
-static __inline__ void enable_dma_buffer0(unsigned int dmanr)
+static inline void enable_dma_buffer0(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	au_writel(DMA_BE0, chan->io + DMA_MODE_SET);
 }
-static __inline__ void enable_dma_buffer1(unsigned int dmanr)
+
+static inline void enable_dma_buffer1(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	au_writel(DMA_BE1, chan->io + DMA_MODE_SET);
 }
-static __inline__ void enable_dma_buffers(unsigned int dmanr)
+static inline void enable_dma_buffers(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
 }
 
-static __inline__ void start_dma(unsigned int dmanr)
+static inline void start_dma(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
-
 	au_writel(DMA_GO, chan->io + DMA_MODE_SET);
 }
 
 #define DMA_HALT_POLL 0x5000
 
-static __inline__ void halt_dma(unsigned int dmanr)
+static inline void halt_dma(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
 	int i;
+
 	if (!chan)
 		return;
-
 	au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
-	// poll the halt bit
+
+	/* Poll the halt bit */
 	for (i = 0; i < DMA_HALT_POLL; i++)
 		if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
 			break;
@@ -205,55 +210,57 @@
 		printk(KERN_INFO "halt_dma: HALT poll expired!\n");
 }
 
-
-static __inline__ void disable_dma(unsigned int dmanr)
+static inline void disable_dma(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 
 	halt_dma(dmanr);
 
-	// now we can disable the buffers
+	/* Now we can disable the buffers */
 	au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
 }
 
-static __inline__ int dma_halted(unsigned int dmanr)
+static inline int dma_halted(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return 1;
 	return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
 }
 
-/* initialize a DMA channel */
-static __inline__ void init_dma(unsigned int dmanr)
+/* Initialize a DMA channel. */
+static inline void init_dma(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
 	u32 mode;
+
 	if (!chan)
 		return;
 
 	disable_dma(dmanr);
 
-	// set device FIFO address
-	au_writel(CPHYSADDR(chan->fifo_addr),
-		  chan->io + DMA_PERIPHERAL_ADDR);
+	/* Set device FIFO address */
+	au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR);
 
 	mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
 	if (chan->irq)
 		mode |= DMA_IE;
 
 	au_writel(~mode, chan->io + DMA_MODE_CLEAR);
-	au_writel(mode, chan->io + DMA_MODE_SET);
+	au_writel(mode,  chan->io + DMA_MODE_SET);
 }
 
 /*
- * set mode for a specific DMA channel
+ * Set mode for a specific DMA channel
  */
-static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode)
+static inline void set_dma_mode(unsigned int dmanr, unsigned int mode)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	/*
@@ -266,36 +273,37 @@
 	chan->mode |= mode;
 }
 
-static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
+static inline unsigned int get_dma_mode(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return 0;
 	return chan->mode;
 }
 
-static __inline__ int get_dma_active_buffer(unsigned int dmanr)
+static inline int get_dma_active_buffer(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return -1;
 	return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
 }
 
-
 /*
- * set the device FIFO address for a specific DMA channel - only
+ * Set the device FIFO address for a specific DMA channel - only
  * applicable to GPO4 and GPO5. All the other devices have fixed
  * FIFO addresses.
  */
-static __inline__ void set_dma_fifo_addr(unsigned int dmanr,
-					 unsigned int a)
+static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 
-	if (chan->mode & DMA_DS)	/* second bank of device ids */
+	if (chan->mode & DMA_DS)	/* second bank of device IDs */
 		return;
 
 	if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
@@ -307,16 +315,19 @@
 /*
  * Clear the DMA buffer done bits in the mode register.
  */
-static __inline__ void clear_dma_done0(unsigned int dmanr)
+static inline void clear_dma_done0(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
 }
-static __inline__ void clear_dma_done1(unsigned int dmanr)
+
+static inline void clear_dma_done1(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
@@ -325,16 +336,17 @@
 /*
  * This does nothing - not applicable to Au1000 DMA.
  */
-static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+static inline void set_dma_page(unsigned int dmanr, char pagenr)
 {
 }
 
 /*
  * Set Buffer 0 transfer address for specific DMA channel.
  */
-static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a)
+static inline void set_dma_addr0(unsigned int dmanr, unsigned int a)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	au_writel(a, chan->io + DMA_BUFFER0_START);
@@ -343,9 +355,10 @@
 /*
  * Set Buffer 1 transfer address for specific DMA channel.
  */
-static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a)
+static inline void set_dma_addr1(unsigned int dmanr, unsigned int a)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	au_writel(a, chan->io + DMA_BUFFER1_START);
@@ -355,10 +368,10 @@
 /*
  * Set Buffer 0 transfer size (max 64k) for a specific DMA channel.
  */
-static __inline__ void set_dma_count0(unsigned int dmanr,
-				      unsigned int count)
+static inline void set_dma_count0(unsigned int dmanr, unsigned int count)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	count &= DMA_COUNT_MASK;
@@ -368,10 +381,10 @@
 /*
  * Set Buffer 1 transfer size (max 64k) for a specific DMA channel.
  */
-static __inline__ void set_dma_count1(unsigned int dmanr,
-				      unsigned int count)
+static inline void set_dma_count1(unsigned int dmanr, unsigned int count)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	count &= DMA_COUNT_MASK;
@@ -381,10 +394,10 @@
 /*
  * Set both buffer transfer sizes (max 64k) for a specific DMA channel.
  */
-static __inline__ void set_dma_count(unsigned int dmanr,
-				     unsigned int count)
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return;
 	count &= DMA_COUNT_MASK;
@@ -396,35 +409,36 @@
  * Returns which buffer has its done bit set in the mode register.
  * Returns -1 if neither or both done bits set.
  */
-static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr)
+static inline unsigned int get_dma_buffer_done(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return 0;
-
-    return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
+	return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
 }
 
 
 /*
  * Returns the DMA channel's Buffer Done IRQ number.
  */
-static __inline__ int get_dma_done_irq(unsigned int dmanr)
+static inline int get_dma_done_irq(unsigned int dmanr)
 {
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return -1;
-
 	return chan->irq;
 }
 
 /*
  * Get DMA residue count. Returns the number of _bytes_ left to transfer.
  */
-static __inline__ int get_dma_residue(unsigned int dmanr)
+static inline int get_dma_residue(unsigned int dmanr)
 {
 	int curBufCntReg, count;
 	struct dma_chan *chan = get_dma_chan(dmanr);
+
 	if (!chan)
 		return 0;
 
@@ -442,4 +456,3 @@
 }
 
 #endif /* __ASM_AU1000_DMA_H */
-
diff --git a/include/asm-mips/mach-au1x00/au1000_gpio.h b/include/asm-mips/mach-au1x00/au1000_gpio.h
index 298f920..d8c96fd 100644
--- a/include/asm-mips/mach-au1x00/au1000_gpio.h
+++ b/include/asm-mips/mach-au1x00/au1000_gpio.h
@@ -2,12 +2,12 @@
  * FILE NAME au1000_gpio.h
  *
  * BRIEF MODULE DESCRIPTION
- *	API to Alchemy Au1000 GPIO device.
+ *	API to Alchemy Au1xx0 GPIO device.
  *
  *  Author: MontaVista Software, Inc.  <source@mvista.com>
- *          Steve Longerbeam <stevel@mvista.com>
+ *          Steve Longerbeam
  *
- * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2001, 2008 MontaVista Software 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
@@ -37,12 +37,12 @@
 
 #define AU1000GPIO_IOC_MAGIC 'A'
 
-#define AU1000GPIO_IN		_IOR (AU1000GPIO_IOC_MAGIC, 0, int)
-#define AU1000GPIO_SET		_IOW (AU1000GPIO_IOC_MAGIC, 1, int)
-#define AU1000GPIO_CLEAR	_IOW (AU1000GPIO_IOC_MAGIC, 2, int)
-#define AU1000GPIO_OUT		_IOW (AU1000GPIO_IOC_MAGIC, 3, int)
-#define AU1000GPIO_TRISTATE	_IOW (AU1000GPIO_IOC_MAGIC, 4, int)
-#define AU1000GPIO_AVAIL_MASK	_IOR (AU1000GPIO_IOC_MAGIC, 5, int)
+#define AU1000GPIO_IN		_IOR(AU1000GPIO_IOC_MAGIC, 0, int)
+#define AU1000GPIO_SET		_IOW(AU1000GPIO_IOC_MAGIC, 1, int)
+#define AU1000GPIO_CLEAR	_IOW(AU1000GPIO_IOC_MAGIC, 2, int)
+#define AU1000GPIO_OUT		_IOW(AU1000GPIO_IOC_MAGIC, 3, int)
+#define AU1000GPIO_TRISTATE	_IOW(AU1000GPIO_IOC_MAGIC, 4, int)
+#define AU1000GPIO_AVAIL_MASK	_IOR(AU1000GPIO_IOC_MAGIC, 5, int)
 
 #ifdef __KERNEL__
 extern u32 get_au1000_avail_gpio_mask(void);
diff --git a/include/asm-mips/mach-au1x00/au1550_spi.h b/include/asm-mips/mach-au1x00/au1550_spi.h
index c2f0466..40e6c48 100644
--- a/include/asm-mips/mach-au1x00/au1550_spi.h
+++ b/include/asm-mips/mach-au1x00/au1550_spi.h
@@ -1,5 +1,5 @@
 /*
- * au1550_spi.h - au1550 psc spi controller driver - platform data struct
+ * au1550_spi.h - Au1550 PSC SPI controller driver - platform data structure
  */
 
 #ifndef _AU1550_SPI_H_
diff --git a/include/asm-mips/mach-au1x00/au1xxx.h b/include/asm-mips/mach-au1x00/au1xxx.h
index 9471359..1b36550 100644
--- a/include/asm-mips/mach-au1x00/au1xxx.h
+++ b/include/asm-mips/mach-au1x00/au1xxx.h
@@ -23,10 +23,10 @@
 #ifndef _AU1XXX_H_
 #define _AU1XXX_H_
 
-
 #include <asm/mach-au1x00/au1000.h>
 
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
+    defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
 #include <asm/mach-db1x00/db1x00.h>
 
 #elif defined(CONFIG_MIPS_PB1550)
diff --git a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
index 93d507c..ad17d7c 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_dbdma.h
@@ -28,17 +28,18 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* Specifics for the Au1xxx Descriptor-Based DMA Controllers, first
- * seen in the AU1550 part.
+/*
+ * Specifics for the Au1xxx Descriptor-Based DMA Controller,
+ * first seen in the AU1550 part.
  */
 #ifndef _AU1000_DBDMA_H_
 #define _AU1000_DBDMA_H_
 
-
 #ifndef _LANGUAGE_ASSEMBLY
 
-/* The DMA base addresses.
- * The Channels are every 256 bytes (0x0100) from the channel 0 base.
+/*
+ * The DMA base addresses.
+ * The channels are every 256 bytes (0x0100) from the channel 0 base.
  * Interrupt status/enable is bits 15:0 for channels 15 to zero.
  */
 #define DDMA_GLOBAL_BASE	0xb4003000
@@ -51,16 +52,14 @@
 	u32	ddma_inten;
 } dbdma_global_t;
 
-/* General Configuration.
-*/
+/* General Configuration. */
 #define DDMA_CONFIG_AF		(1 << 2)
 #define DDMA_CONFIG_AH		(1 << 1)
 #define DDMA_CONFIG_AL		(1 << 0)
 
 #define DDMA_THROTTLE_EN	(1 << 31)
 
-/* The structure of a DMA Channel.
-*/
+/* The structure of a DMA Channel. */
 typedef volatile struct au1xxx_dma_channel {
 	u32	ddma_cfg;	/* See below */
 	u32	ddma_desptr;	/* 32-byte aligned pointer to descriptor */
@@ -69,8 +68,7 @@
 	u32	ddma_irq;	/* If bit 0 set, interrupt pending */
 	u32	ddma_stat;	/* See below */
 	u32	ddma_bytecnt;	/* Byte count, valid only when chan idle */
-	/* Remainder, up to the 256 byte boundary, is reserved.
-	*/
+	/* Remainder, up to the 256 byte boundary, is reserved. */
 } au1x_dma_chan_t;
 
 #define DDMA_CFG_SED	(1 << 9)	/* source DMA level/edge detect */
@@ -84,7 +82,8 @@
 #define DDMA_CFG_DBE	(1 << 1)	/* Destination big endian */
 #define DDMA_CFG_EN	(1 << 0)	/* Channel enable */
 
-/* Always set when descriptor processing done, regardless of
+/*
+ * Always set when descriptor processing done, regardless of
  * interrupt enable state.  Reflected in global intstat, don't
  * clear this until global intstat is read/used.
  */
@@ -94,7 +93,8 @@
 #define DDMA_STAT_V	(1 << 1)	/* Descriptor valid */
 #define DDMA_STAT_H	(1 << 0)	/* Channel Halted */
 
-/* "Standard" DDMA Descriptor.
+/*
+ * "Standard" DDMA Descriptor.
  * Must be 32-byte aligned.
  */
 typedef volatile struct au1xxx_ddma_desc {
@@ -106,8 +106,9 @@
 	u32	dscr_dest1;		/* See below */
 	u32	dscr_stat;		/* completion status */
 	u32	dscr_nxtptr;		/* Next descriptor pointer (mostly) */
-	/* First 32bytes are HW specific!!!
-	   Lets have some SW data following.. make sure its 32bytes
+	/*
+	 * First 32 bytes are HW specific!!!
+	 * Lets have some SW data following -- make sure it's 32 bytes.
 	 */
 	u32	sw_status;
 	u32 	sw_context;
@@ -130,10 +131,9 @@
 #define DSCR_CMD0_CV		(0x1 << 2)	/* Clear Valid when done */
 #define DSCR_CMD0_ST_MASK	(0x3 << 0)	/* Status instruction */
 
-#define SW_STATUS_INUSE		(1<<0)
+#define SW_STATUS_INUSE 	(1 << 0)
 
-/* Command 0 device IDs.
-*/
+/* Command 0 device IDs. */
 #ifdef CONFIG_SOC_AU1550
 #define DSCR_CMD0_UART0_TX	0
 #define DSCR_CMD0_UART0_RX	1
@@ -198,16 +198,15 @@
 #define DSCR_CMD0_THROTTLE	30
 #define DSCR_CMD0_ALWAYS	31
 #define DSCR_NDEV_IDS		32
-/* THis macro is used to find/create custom device types */
-#define DSCR_DEV2CUSTOM_ID(x, d)	(((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF))
-#define DSCR_CUSTOM2DEV_ID(x)	((x)&0xFF)
-
+/* This macro is used to find/create custom device types */
+#define DSCR_DEV2CUSTOM_ID(x, d) (((((x) & 0xFFFF) << 8) | 0x32000000) | \
+				  ((d) & 0xFF))
+#define DSCR_CUSTOM2DEV_ID(x)	((x) & 0xFF)
 
 #define DSCR_CMD0_SID(x)	(((x) & 0x1f) << 25)
 #define DSCR_CMD0_DID(x)	(((x) & 0x1f) << 20)
 
-/* Source/Destination transfer width.
-*/
+/* Source/Destination transfer width. */
 #define DSCR_CMD0_BYTE		0
 #define DSCR_CMD0_HALFWORD	1
 #define DSCR_CMD0_WORD		2
@@ -215,16 +214,14 @@
 #define DSCR_CMD0_SW(x)		(((x) & 0x3) << 18)
 #define DSCR_CMD0_DW(x)		(((x) & 0x3) << 16)
 
-/* DDMA Descriptor Type.
-*/
+/* DDMA Descriptor Type. */
 #define DSCR_CMD0_STANDARD	0
 #define DSCR_CMD0_LITERAL	1
 #define DSCR_CMD0_CMP_BRANCH	2
 
 #define DSCR_CMD0_DT(x)		(((x) & 0x3) << 13)
 
-/* Status Instruction.
-*/
+/* Status Instruction. */
 #define DSCR_CMD0_ST_NOCHANGE	0	/* Don't change */
 #define DSCR_CMD0_ST_CURRENT	1	/* Write current status */
 #define DSCR_CMD0_ST_CMD0	2	/* Write cmd0 with V cleared */
@@ -232,23 +229,20 @@
 
 #define DSCR_CMD0_ST(x)		(((x) & 0x3) << 0)
 
-/* Descriptor Command 1
-*/
+/* Descriptor Command 1. */
 #define DSCR_CMD1_SUPTR_MASK	(0xf << 28)	/* upper 4 bits of src addr */
 #define DSCR_CMD1_DUPTR_MASK	(0xf << 24)	/* upper 4 bits of dest addr */
 #define DSCR_CMD1_FL_MASK	(0x3 << 22)	/* Flag bits */
 #define DSCR_CMD1_BC_MASK	(0x3fffff)	/* Byte count */
 
-/* Flag description.
-*/
+/* Flag description. */
 #define DSCR_CMD1_FL_MEM_STRIDE0	0
 #define DSCR_CMD1_FL_MEM_STRIDE1	1
 #define DSCR_CMD1_FL_MEM_STRIDE2	2
 
 #define DSCR_CMD1_FL(x)		(((x) & 0x3) << 22)
 
-/* Source1, 1-dimensional stride.
-*/
+/* Source1, 1-dimensional stride. */
 #define DSCR_SRC1_STS_MASK	(3 << 30)	/* Src xfer size */
 #define DSCR_SRC1_SAM_MASK	(3 << 28)	/* Src xfer movement */
 #define DSCR_SRC1_SB_MASK	(0x3fff << 14)	/* Block size */
@@ -256,8 +250,7 @@
 #define DSCR_SRC1_SS_MASK	(0x3fff << 0)	/* Stride */
 #define DSCR_SRC1_SS(x)		(((x) & 0x3fff) << 0)
 
-/* Dest1, 1-dimensional stride.
-*/
+/* Dest1, 1-dimensional stride. */
 #define DSCR_DEST1_DTS_MASK	(3 << 30)	/* Dest xfer size */
 #define DSCR_DEST1_DAM_MASK	(3 << 28)	/* Dest xfer movement */
 #define DSCR_DEST1_DB_MASK	(0x3fff << 14)	/* Block size */
@@ -279,29 +272,27 @@
 #define DSCR_SRC1_SAM(x)	(((x) & 3) << 28)
 #define DSCR_DEST1_DAM(x)	(((x) & 3) << 28)
 
-/* The next descriptor pointer.
-*/
+/* The next descriptor pointer. */
 #define DSCR_NXTPTR_MASK	(0x07ffffff)
 #define DSCR_NXTPTR(x)		((x) >> 5)
 #define DSCR_GET_NXTPTR(x)	((x) << 5)
 #define DSCR_NXTPTR_MS		(1 << 27)
 
-/* The number of DBDMA channels.
-*/
+/* The number of DBDMA channels. */
 #define NUM_DBDMA_CHANS	16
 
 /*
- * Ddma API definitions
+ * DDMA API definitions
  * FIXME: may not fit to this header file
  */
 typedef struct dbdma_device_table {
-	u32		dev_id;
-	u32		dev_flags;
-	u32		dev_tsize;
-	u32		dev_devwidth;
-	u32		dev_physaddr;		/* If FIFO */
-	u32		dev_intlevel;
-	u32		dev_intpolarity;
+	u32	dev_id;
+	u32	dev_flags;
+	u32	dev_tsize;
+	u32	dev_devwidth;
+	u32	dev_physaddr;		/* If FIFO */
+	u32	dev_intlevel;
+	u32	dev_intpolarity;
 } dbdev_tab_t;
 
 
@@ -316,44 +307,41 @@
 	au1x_ddma_desc_t	*chan_desc_base;
 	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
 	void			*chan_callparam;
-	void (*chan_callback)(int, void *);
+	void			(*chan_callback)(int, void *);
 } chan_tab_t;
 
 #define DEV_FLAGS_INUSE		(1 << 0)
 #define DEV_FLAGS_ANYUSE	(1 << 1)
 #define DEV_FLAGS_OUT		(1 << 2)
 #define DEV_FLAGS_IN		(1 << 3)
-#define DEV_FLAGS_BURSTABLE (1 << 4)
+#define DEV_FLAGS_BURSTABLE	(1 << 4)
 #define DEV_FLAGS_SYNC		(1 << 5)
-/* end Ddma API definitions */
+/* end DDMA API definitions */
 
-/* External functions for drivers to use.
-*/
-/* Use this to allocate a dbdma channel.  The device ids are one of the
- * DSCR_CMD0 devices IDs, which is usually redefined to a more
- * meaningful name.  The 'callback' is called during dma completion
+/*
+ * External functions for drivers to use.
+ * Use this to allocate a DBDMA channel.  The device IDs are one of
+ * the DSCR_CMD0 devices IDs, which is usually redefined to a more
+ * meaningful name.  The 'callback' is called during DMA completion
  * interrupt.
  */
 extern u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
-	void (*callback)(int, void *), void *callparam);
+				   void (*callback)(int, void *),
+				   void *callparam);
 
 #define DBDMA_MEM_CHAN	DSCR_CMD0_ALWAYS
 
-/* Set the device width of a in/out fifo.
-*/
+/* Set the device width of an in/out FIFO. */
 u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
 
-/* Allocate a ring of descriptors for dbdma.
-*/
+/* Allocate a ring of descriptors for DBDMA. */
 u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
 
-/* Put buffers on source/destination descriptors.
-*/
+/* Put buffers on source/destination descriptors. */
 u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags);
 u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags);
 
-/* Get a buffer from the destination descriptor.
-*/
+/* Get a buffer from the destination descriptor. */
 u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
 
 void au1xxx_dbdma_stop(u32 chanid);
@@ -364,29 +352,34 @@
 void au1xxx_dbdma_chan_free(u32 chanid);
 void au1xxx_dbdma_dump(u32 chanid);
 
-u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr );
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);
 
-u32 au1xxx_ddma_add_device( dbdev_tab_t *dev );
-void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
+u32 au1xxx_ddma_add_device(dbdev_tab_t *dev);
+void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
 
 /*
- 	Some compatibilty macros --
-		Needed to make changes to API without breaking existing drivers
-*/
-#define	au1xxx_dbdma_put_source(chanid, buf, nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
-#define	au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
-#define	put_source_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
+ * Some compatibilty macros -- needed to make changes to API
+ * without breaking existing drivers.
+ */
+#define au1xxx_dbdma_put_source(chanid, buf, nbytes)			\
+	_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)	\
+	_au1xxx_dbdma_put_source(chanid, buf, nbytes, flags)
+#define put_source_flags(chanid, buf, nbytes, flags)			\
+	au1xxx_dbdma_put_source_flags(chanid, buf, nbytes, flags)
 
-
-#define au1xxx_dbdma_put_dest(chanid, buf, nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
-#define	au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
-#define	put_dest_flags(chanid, buf, nbytes, flags) au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
+#define au1xxx_dbdma_put_dest(chanid, buf, nbytes)			\
+	_au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE)
+#define au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags) 	\
+	_au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags)
+#define put_dest_flags(chanid, buf, nbytes, flags)			\
+	au1xxx_dbdma_put_dest_flags(chanid, buf, nbytes, flags)
 
 /*
  *	Flags for the put_source/put_dest functions.
  */
-#define DDMA_FLAGS_IE	(1<<0)
-#define DDMA_FLAGS_NOIE (1<<1)
+#define DDMA_FLAGS_IE	(1 << 0)
+#define DDMA_FLAGS_NOIE (1 << 1)
 
 #endif /* _LANGUAGE_ASSEMBLY */
 #endif /* _AU1000_DBDMA_H_ */
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
index b493a5e..60638b8 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_ide.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -31,167 +31,164 @@
  */
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        #define DMA_WAIT_TIMEOUT        100
-        #define NUM_DESCRIPTORS         PRD_ENTRIES
+#define DMA_WAIT_TIMEOUT	100
+#define NUM_DESCRIPTORS 	PRD_ENTRIES
 #else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
-        #define NUM_DESCRIPTORS         2
+#define NUM_DESCRIPTORS 	2
 #endif
 
 #ifndef AU1XXX_ATA_RQSIZE
-        #define AU1XXX_ATA_RQSIZE       128
+#define AU1XXX_ATA_RQSIZE	128
 #endif
 
 /* Disable Burstable-Support for DBDMA */
 #ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
-        #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON  0
+#define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON	0
 #endif
 
 #ifdef CONFIG_PM
 /*
-* This will enable the device to be powered up when write() or read()
-* is called. If this is not defined, the driver will return -EBUSY.
-*/
+ * This will enable the device to be powered up when write() or read()
+ * is called. If this is not defined, the driver will return -EBUSY.
+ */
 #define WAKE_ON_ACCESS 1
 
-typedef struct
-{
-        spinlock_t         lock;       /* Used to block on state transitions */
-        au1xxx_power_dev_t *dev;       /* Power Managers device structure */
-        unsigned	   stopped;    /* USed to signaling device is stopped */
+typedef struct {
+	spinlock_t		lock;	/* Used to block on state transitions */
+	au1xxx_power_dev_t	*dev;	/* Power Managers device structure */
+	unsigned		stopped; /* Used to signal device is stopped */
 } pm_state;
 #endif
 
-
-typedef struct
-{
-        u32                     tx_dev_id, rx_dev_id, target_dev_id;
-        u32                     tx_chan, rx_chan;
-        void                    *tx_desc_head, *rx_desc_head;
-        ide_hwif_t              *hwif;
+typedef struct {
+	u32			tx_dev_id, rx_dev_id, target_dev_id;
+	u32			tx_chan, rx_chan;
+	void			*tx_desc_head, *rx_desc_head;
+	ide_hwif_t		*hwif;
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        ide_drive_t             *drive;
-        struct dbdma_cmd        *dma_table_cpu;
-        dma_addr_t              dma_table_dma;
+	ide_drive_t		*drive;
+	struct dbdma_cmd	*dma_table_cpu;
+	dma_addr_t		dma_table_dma;
 #endif
 	int			irq;
 	u32			regbase;
 #ifdef CONFIG_PM
-        pm_state                pm;
+	pm_state		pm;
 #endif
 } _auide_hwif;
 
-/*******************************************************************************
-* PIO Mode timing calculation :                                                *
-*                                                                              *
-* Static Bus Spec   ATA Spec                                                   *
-*      Tcsoe      =   t1                                                       *
-*      Toecs      =   t9                                                       *
-*      Twcs       =   t9                                                       *
-*      Tcsh       =   t2i | t2                                                 *
-*      Tcsoff     =   t2i | t2                                                 *
-*      Twp        =   t2                                                       *
-*      Tcsw       =   t1                                                       *
-*      Tpm        =   0                                                        *
-*      Ta         =   t1+t2                                                    *
-*******************************************************************************/
+/******************************************************************************/
+/* PIO Mode timing calculation :					      */
+/*									      */
+/* Static Bus Spec   ATA Spec						      */
+/*	Tcsoe	   =	t1						      */
+/*	Toecs	   =	t9						      */
+/*	Twcs	   =	t9						      */
+/*	Tcsh	   =	t2i | t2					      */
+/*	Tcsoff	   =	t2i | t2					      */
+/*	Twp	   =	t2						      */
+/*	Tcsw	   =	t1						      */
+/*	Tpm	   =	0						      */
+/*	Ta	   =	t1+t2						      */
+/******************************************************************************/
 
-#define TCSOE_MASK            (0x07<<29)
-#define TOECS_MASK            (0x07<<26)
-#define TWCS_MASK             (0x07<<28)
-#define TCSH_MASK             (0x0F<<24)
-#define TCSOFF_MASK           (0x07<<20)
-#define TWP_MASK              (0x3F<<14)
-#define TCSW_MASK             (0x0F<<10)
-#define TPM_MASK              (0x0F<<6)
-#define TA_MASK               (0x3F<<0)
-#define TS_MASK               (1<<8)
+#define TCSOE_MASK		(0x07 << 29)
+#define TOECS_MASK		(0x07 << 26)
+#define TWCS_MASK		(0x07 << 28)
+#define TCSH_MASK		(0x0F << 24)
+#define TCSOFF_MASK		(0x07 << 20)
+#define TWP_MASK		(0x3F << 14)
+#define TCSW_MASK		(0x0F << 10)
+#define TPM_MASK		(0x0F << 6)
+#define TA_MASK 		(0x3F << 0)
+#define TS_MASK 		(1 << 8)
 
 /* Timing parameters PIO mode 0 */
-#define SBC_IDE_PIO0_TCSOE    (0x04<<29)
-#define SBC_IDE_PIO0_TOECS    (0x01<<26)
-#define SBC_IDE_PIO0_TWCS     (0x02<<28)
-#define SBC_IDE_PIO0_TCSH     (0x08<<24)
-#define SBC_IDE_PIO0_TCSOFF   (0x07<<20)
-#define SBC_IDE_PIO0_TWP      (0x10<<14)
-#define SBC_IDE_PIO0_TCSW     (0x04<<10)
-#define SBC_IDE_PIO0_TPM      (0x0<<6)
-#define SBC_IDE_PIO0_TA       (0x15<<0)
+#define SBC_IDE_PIO0_TCSOE	(0x04 << 29)
+#define SBC_IDE_PIO0_TOECS	(0x01 << 26)
+#define SBC_IDE_PIO0_TWCS	(0x02 << 28)
+#define SBC_IDE_PIO0_TCSH	(0x08 << 24)
+#define SBC_IDE_PIO0_TCSOFF	(0x07 << 20)
+#define SBC_IDE_PIO0_TWP	(0x10 << 14)
+#define SBC_IDE_PIO0_TCSW	(0x04 << 10)
+#define SBC_IDE_PIO0_TPM	(0x00 << 6)
+#define SBC_IDE_PIO0_TA 	(0x15 << 0)
 /* Timing parameters PIO mode 1 */
-#define SBC_IDE_PIO1_TCSOE    (0x03<<29)
-#define SBC_IDE_PIO1_TOECS    (0x01<<26)
-#define SBC_IDE_PIO1_TWCS     (0x01<<28)
-#define SBC_IDE_PIO1_TCSH     (0x06<<24)
-#define SBC_IDE_PIO1_TCSOFF   (0x06<<20)
-#define SBC_IDE_PIO1_TWP      (0x08<<14)
-#define SBC_IDE_PIO1_TCSW     (0x03<<10)
-#define SBC_IDE_PIO1_TPM      (0x00<<6)
-#define SBC_IDE_PIO1_TA       (0x0B<<0)
+#define SBC_IDE_PIO1_TCSOE	(0x03 << 29)
+#define SBC_IDE_PIO1_TOECS	(0x01 << 26)
+#define SBC_IDE_PIO1_TWCS	(0x01 << 28)
+#define SBC_IDE_PIO1_TCSH	(0x06 << 24)
+#define SBC_IDE_PIO1_TCSOFF	(0x06 << 20)
+#define SBC_IDE_PIO1_TWP	(0x08 << 14)
+#define SBC_IDE_PIO1_TCSW	(0x03 << 10)
+#define SBC_IDE_PIO1_TPM	(0x00 << 6)
+#define SBC_IDE_PIO1_TA 	(0x0B << 0)
 /* Timing parameters PIO mode 2 */
-#define SBC_IDE_PIO2_TCSOE    (0x05<<29)
-#define SBC_IDE_PIO2_TOECS    (0x01<<26)
-#define SBC_IDE_PIO2_TWCS     (0x01<<28)
-#define SBC_IDE_PIO2_TCSH     (0x07<<24)
-#define SBC_IDE_PIO2_TCSOFF   (0x07<<20)
-#define SBC_IDE_PIO2_TWP      (0x1F<<14)
-#define SBC_IDE_PIO2_TCSW     (0x05<<10)
-#define SBC_IDE_PIO2_TPM      (0x00<<6)
-#define SBC_IDE_PIO2_TA       (0x22<<0)
+#define SBC_IDE_PIO2_TCSOE	(0x05 << 29)
+#define SBC_IDE_PIO2_TOECS	(0x01 << 26)
+#define SBC_IDE_PIO2_TWCS	(0x01 << 28)
+#define SBC_IDE_PIO2_TCSH	(0x07 << 24)
+#define SBC_IDE_PIO2_TCSOFF	(0x07 << 20)
+#define SBC_IDE_PIO2_TWP	(0x1F << 14)
+#define SBC_IDE_PIO2_TCSW	(0x05 << 10)
+#define SBC_IDE_PIO2_TPM	(0x00 << 6)
+#define SBC_IDE_PIO2_TA 	(0x22 << 0)
 /* Timing parameters PIO mode 3 */
-#define SBC_IDE_PIO3_TCSOE    (0x05<<29)
-#define SBC_IDE_PIO3_TOECS    (0x01<<26)
-#define SBC_IDE_PIO3_TWCS     (0x01<<28)
-#define SBC_IDE_PIO3_TCSH     (0x0D<<24)
-#define SBC_IDE_PIO3_TCSOFF   (0x0D<<20)
-#define SBC_IDE_PIO3_TWP      (0x15<<14)
-#define SBC_IDE_PIO3_TCSW     (0x05<<10)
-#define SBC_IDE_PIO3_TPM      (0x00<<6)
-#define SBC_IDE_PIO3_TA       (0x1A<<0)
+#define SBC_IDE_PIO3_TCSOE	(0x05 << 29)
+#define SBC_IDE_PIO3_TOECS	(0x01 << 26)
+#define SBC_IDE_PIO3_TWCS	(0x01 << 28)
+#define SBC_IDE_PIO3_TCSH	(0x0D << 24)
+#define SBC_IDE_PIO3_TCSOFF	(0x0D << 20)
+#define SBC_IDE_PIO3_TWP	(0x15 << 14)
+#define SBC_IDE_PIO3_TCSW	(0x05 << 10)
+#define SBC_IDE_PIO3_TPM	(0x00 << 6)
+#define SBC_IDE_PIO3_TA 	(0x1A << 0)
 /* Timing parameters PIO mode 4 */
-#define SBC_IDE_PIO4_TCSOE    (0x04<<29)
-#define SBC_IDE_PIO4_TOECS    (0x01<<26)
-#define SBC_IDE_PIO4_TWCS     (0x01<<28)
-#define SBC_IDE_PIO4_TCSH     (0x04<<24)
-#define SBC_IDE_PIO4_TCSOFF   (0x04<<20)
-#define SBC_IDE_PIO4_TWP      (0x0D<<14)
-#define SBC_IDE_PIO4_TCSW     (0x03<<10)
-#define SBC_IDE_PIO4_TPM      (0x00<<6)
-#define SBC_IDE_PIO4_TA       (0x12<<0)
+#define SBC_IDE_PIO4_TCSOE	(0x04 << 29)
+#define SBC_IDE_PIO4_TOECS	(0x01 << 26)
+#define SBC_IDE_PIO4_TWCS	(0x01 << 28)
+#define SBC_IDE_PIO4_TCSH	(0x04 << 24)
+#define SBC_IDE_PIO4_TCSOFF	(0x04 << 20)
+#define SBC_IDE_PIO4_TWP	(0x0D << 14)
+#define SBC_IDE_PIO4_TCSW	(0x03 << 10)
+#define SBC_IDE_PIO4_TPM	(0x00 << 6)
+#define SBC_IDE_PIO4_TA 	(0x12 << 0)
 /* Timing parameters MDMA mode 0 */
-#define SBC_IDE_MDMA0_TCSOE   (0x03<<29)
-#define SBC_IDE_MDMA0_TOECS   (0x01<<26)
-#define SBC_IDE_MDMA0_TWCS    (0x01<<28)
-#define SBC_IDE_MDMA0_TCSH    (0x07<<24)
-#define SBC_IDE_MDMA0_TCSOFF  (0x07<<20)
-#define SBC_IDE_MDMA0_TWP     (0x0C<<14)
-#define SBC_IDE_MDMA0_TCSW    (0x03<<10)
-#define SBC_IDE_MDMA0_TPM     (0x00<<6)
-#define SBC_IDE_MDMA0_TA      (0x0F<<0)
+#define SBC_IDE_MDMA0_TCSOE	(0x03 << 29)
+#define SBC_IDE_MDMA0_TOECS	(0x01 << 26)
+#define SBC_IDE_MDMA0_TWCS	(0x01 << 28)
+#define SBC_IDE_MDMA0_TCSH	(0x07 << 24)
+#define SBC_IDE_MDMA0_TCSOFF	(0x07 << 20)
+#define SBC_IDE_MDMA0_TWP	(0x0C << 14)
+#define SBC_IDE_MDMA0_TCSW	(0x03 << 10)
+#define SBC_IDE_MDMA0_TPM	(0x00 << 6)
+#define SBC_IDE_MDMA0_TA	(0x0F << 0)
 /* Timing parameters MDMA mode 1 */
-#define SBC_IDE_MDMA1_TCSOE   (0x05<<29)
-#define SBC_IDE_MDMA1_TOECS   (0x01<<26)
-#define SBC_IDE_MDMA1_TWCS    (0x01<<28)
-#define SBC_IDE_MDMA1_TCSH    (0x05<<24)
-#define SBC_IDE_MDMA1_TCSOFF  (0x05<<20)
-#define SBC_IDE_MDMA1_TWP     (0x0F<<14)
-#define SBC_IDE_MDMA1_TCSW    (0x05<<10)
-#define SBC_IDE_MDMA1_TPM     (0x00<<6)
-#define SBC_IDE_MDMA1_TA      (0x15<<0)
+#define SBC_IDE_MDMA1_TCSOE	(0x05 << 29)
+#define SBC_IDE_MDMA1_TOECS	(0x01 << 26)
+#define SBC_IDE_MDMA1_TWCS	(0x01 << 28)
+#define SBC_IDE_MDMA1_TCSH	(0x05 << 24)
+#define SBC_IDE_MDMA1_TCSOFF	(0x05 << 20)
+#define SBC_IDE_MDMA1_TWP	(0x0F << 14)
+#define SBC_IDE_MDMA1_TCSW	(0x05 << 10)
+#define SBC_IDE_MDMA1_TPM	(0x00 << 6)
+#define SBC_IDE_MDMA1_TA	(0x15 << 0)
 /* Timing parameters MDMA mode 2 */
-#define SBC_IDE_MDMA2_TCSOE   (0x04<<29)
-#define SBC_IDE_MDMA2_TOECS   (0x01<<26)
-#define SBC_IDE_MDMA2_TWCS    (0x01<<28)
-#define SBC_IDE_MDMA2_TCSH    (0x04<<24)
-#define SBC_IDE_MDMA2_TCSOFF  (0x04<<20)
-#define SBC_IDE_MDMA2_TWP     (0x0D<<14)
-#define SBC_IDE_MDMA2_TCSW    (0x04<<10)
-#define SBC_IDE_MDMA2_TPM     (0x00<<6)
-#define SBC_IDE_MDMA2_TA      (0x12<<0)
+#define SBC_IDE_MDMA2_TCSOE	(0x04 << 29)
+#define SBC_IDE_MDMA2_TOECS	(0x01 << 26)
+#define SBC_IDE_MDMA2_TWCS	(0x01 << 28)
+#define SBC_IDE_MDMA2_TCSH	(0x04 << 24)
+#define SBC_IDE_MDMA2_TCSOFF	(0x04 << 20)
+#define SBC_IDE_MDMA2_TWP	(0x0D << 14)
+#define SBC_IDE_MDMA2_TCSW	(0x04 << 10)
+#define SBC_IDE_MDMA2_TPM	(0x00 << 6)
+#define SBC_IDE_MDMA2_TA	(0x12 << 0)
 
 #define SBC_IDE_TIMING(mode) \
-         SBC_IDE_##mode##_TWCS | \
-         SBC_IDE_##mode##_TCSH | \
-         SBC_IDE_##mode##_TCSOFF | \
-         SBC_IDE_##mode##_TWP | \
-         SBC_IDE_##mode##_TCSW | \
-         SBC_IDE_##mode##_TPM | \
-         SBC_IDE_##mode##_TA
+	(SBC_IDE_##mode##_TWCS | \
+	 SBC_IDE_##mode##_TCSH | \
+	 SBC_IDE_##mode##_TCSOFF | \
+	 SBC_IDE_##mode##_TWP | \
+	 SBC_IDE_##mode##_TCSW | \
+	 SBC_IDE_##mode##_TPM | \
+	 SBC_IDE_##mode##_TA)
diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h
index 1bd4e27..dae4eca 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_psc.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h
@@ -33,7 +33,6 @@
 #ifndef _AU1000_PSC_H_
 #define _AU1000_PSC_H_
 
-
 /* The PSC base addresses.  */
 #ifdef CONFIG_SOC_AU1550
 #define PSC0_BASE_ADDR		0xb1a00000
@@ -47,8 +46,8 @@
 #define PSC1_BASE_ADDR		0xb1b00000
 #endif
 
-/* The PSC select and control registers are common to
- * all protocols.
+/*
+ * The PSC select and control registers are common to all protocols.
  */
 #define PSC_SEL_OFFSET		0x00000000
 #define PSC_CTRL_OFFSET		0x00000004
@@ -59,18 +58,17 @@
 #define PSC_SEL_CLK_SERCLK	(2 << 4)
 
 #define PSC_SEL_PS_MASK		0x00000007
-#define PSC_SEL_PS_DISABLED	(0)
-#define PSC_SEL_PS_SPIMODE	(2)
-#define PSC_SEL_PS_I2SMODE	(3)
-#define PSC_SEL_PS_AC97MODE	(4)
-#define PSC_SEL_PS_SMBUSMODE	(5)
+#define PSC_SEL_PS_DISABLED	0
+#define PSC_SEL_PS_SPIMODE	2
+#define PSC_SEL_PS_I2SMODE	3
+#define PSC_SEL_PS_AC97MODE	4
+#define PSC_SEL_PS_SMBUSMODE	5
 
-#define PSC_CTRL_DISABLE	(0)
-#define PSC_CTRL_SUSPEND	(2)
-#define PSC_CTRL_ENABLE		(3)
+#define PSC_CTRL_DISABLE	0
+#define PSC_CTRL_SUSPEND	2
+#define PSC_CTRL_ENABLE 	3
 
-/* AC97 Registers.
-*/
+/* AC97 Registers. */
 #define PSC_AC97CFG_OFFSET	0x00000008
 #define PSC_AC97MSK_OFFSET	0x0000000c
 #define PSC_AC97PCR_OFFSET	0x00000010
@@ -95,8 +93,7 @@
 #define PSC_AC97GPO		(AC97_PSC_BASE + PSC_AC97GPO_OFFSET)
 #define PSC_AC97GPI		(AC97_PSC_BASE + PSC_AC97GPI_OFFSET)
 
-/* AC97 Config Register.
-*/
+/* AC97 Config Register. */
 #define PSC_AC97CFG_RT_MASK	(3 << 30)
 #define PSC_AC97CFG_RT_FIFO1	(0 << 30)
 #define PSC_AC97CFG_RT_FIFO2	(1 << 30)
@@ -118,20 +115,19 @@
 #define PSC_AC97CFG_RXSLOT_MASK	(0x3ff << 1)
 #define PSC_AC97CFG_GE_ENABLE	(1)
 
-/* Enable slots 3-12.
-*/
+/* Enable slots 3-12. */
 #define PSC_AC97CFG_TXSLOT_ENA(x)	(1 << (((x) - 3) + 11))
 #define PSC_AC97CFG_RXSLOT_ENA(x)	(1 << (((x) - 3) + 1))
 
-/* The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
+/*
+ * The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
  * The only sensible numbers are 7, 9, or possibly 11.  Nah, just do the
  * arithmetic in the macro.
  */
-#define PSC_AC97CFG_SET_LEN(x)	(((((x)-2)/2) & 0xf) << 21)
+#define PSC_AC97CFG_SET_LEN(x)	(((((x) - 2) / 2) & 0xf) << 21)
 #define PSC_AC97CFG_GET_LEN(x)	(((((x) >> 21) & 0xf) * 2) + 2)
 
-/* AC97 Mask Register.
-*/
+/* AC97 Mask Register. */
 #define PSC_AC97MSK_GR		(1 << 25)
 #define PSC_AC97MSK_CD		(1 << 24)
 #define PSC_AC97MSK_RR		(1 << 13)
@@ -148,8 +144,7 @@
 				 PSC_AC97MSK_TO | PSC_AC97MSK_TU | \
 				 PSC_AC97MSK_RD | PSC_AC97MSK_TD)
 
-/* AC97 Protocol Control Register.
-*/
+/* AC97 Protocol Control Register. */
 #define PSC_AC97PCR_RC		(1 << 6)
 #define PSC_AC97PCR_RP		(1 << 5)
 #define PSC_AC97PCR_RS		(1 << 4)
@@ -157,8 +152,7 @@
 #define PSC_AC97PCR_TP		(1 << 1)
 #define PSC_AC97PCR_TS		(1 << 0)
 
-/* AC97 Status register (read only).
-*/
+/* AC97 Status register (read only). */
 #define PSC_AC97STAT_CB		(1 << 26)
 #define PSC_AC97STAT_CP		(1 << 25)
 #define PSC_AC97STAT_CR		(1 << 24)
@@ -174,8 +168,7 @@
 #define PSC_AC97STAT_DR		(1 << 1)
 #define PSC_AC97STAT_SR		(1 << 0)
 
-/* AC97 Event Register.
-*/
+/* AC97 Event Register. */
 #define PSC_AC97EVNT_GR		(1 << 25)
 #define PSC_AC97EVNT_CD		(1 << 24)
 #define PSC_AC97EVNT_RR		(1 << 13)
@@ -187,22 +180,18 @@
 #define PSC_AC97EVNT_RD		(1 << 5)
 #define PSC_AC97EVNT_TD		(1 << 4)
 
-/* CODEC Command Register.
-*/
+/* CODEC Command Register. */
 #define PSC_AC97CDC_RD		(1 << 25)
 #define PSC_AC97CDC_ID_MASK	(3 << 23)
 #define PSC_AC97CDC_INDX_MASK	(0x7f << 16)
-#define PSC_AC97CDC_ID(x)	(((x) & 0x3) << 23)
+#define PSC_AC97CDC_ID(x)	(((x) & 0x03) << 23)
 #define PSC_AC97CDC_INDX(x)	(((x) & 0x7f) << 16)
 
-/* AC97 Reset Control Register.
-*/
+/* AC97 Reset Control Register. */
 #define PSC_AC97RST_RST		(1 << 1)
 #define PSC_AC97RST_SNC		(1 << 0)
 
-
-/* PSC in I2S Mode.
-*/
+/* PSC in I2S Mode. */
 typedef struct	psc_i2s {
 	u32	psc_sel;
 	u32	psc_ctrl;
@@ -215,8 +204,7 @@
 	u32	psc_i2sudf;
 } psc_i2s_t;
 
-/* I2S Config Register.
-*/
+/* I2S Config Register. */
 #define PSC_I2SCFG_RT_MASK	(3 << 30)
 #define PSC_I2SCFG_RT_FIFO1	(0 << 30)
 #define PSC_I2SCFG_RT_FIFO2	(1 << 30)
@@ -247,8 +235,7 @@
 #define PSC_I2SCFG_MLJ		(1 << 10)
 #define PSC_I2SCFG_XM		(1 << 9)
 
-/* The word length equation is simply LEN+1.
- */
+/* The word length equation is simply LEN+1. */
 #define PSC_I2SCFG_SET_LEN(x)	((((x) - 1) & 0x1f) << 4)
 #define PSC_I2SCFG_GET_LEN(x)	((((x) >> 4) & 0x1f) + 1)
 
@@ -256,8 +243,7 @@
 #define PSC_I2SCFG_MLF		(1 << 1)
 #define PSC_I2SCFG_MS		(1 << 0)
 
-/* I2S Mask Register.
-*/
+/* I2S Mask Register. */
 #define PSC_I2SMSK_RR		(1 << 13)
 #define PSC_I2SMSK_RO		(1 << 12)
 #define PSC_I2SMSK_RU		(1 << 11)
@@ -271,8 +257,7 @@
 				 PSC_I2SMSK_TO | PSC_I2SMSK_TU | \
 				 PSC_I2SMSK_RD | PSC_I2SMSK_TD)
 
-/* I2S Protocol Control Register.
-*/
+/* I2S Protocol Control Register. */
 #define PSC_I2SPCR_RC		(1 << 6)
 #define PSC_I2SPCR_RP		(1 << 5)
 #define PSC_I2SPCR_RS		(1 << 4)
@@ -280,8 +265,7 @@
 #define PSC_I2SPCR_TP		(1 << 1)
 #define PSC_I2SPCR_TS		(1 << 0)
 
-/* I2S Status register (read only).
-*/
+/* I2S Status register (read only). */
 #define PSC_I2SSTAT_RF		(1 << 13)
 #define PSC_I2SSTAT_RE		(1 << 12)
 #define PSC_I2SSTAT_RR		(1 << 11)
@@ -294,8 +278,7 @@
 #define PSC_I2SSTAT_DR		(1 << 1)
 #define PSC_I2SSTAT_SR		(1 << 0)
 
-/* I2S Event Register.
-*/
+/* I2S Event Register. */
 #define PSC_I2SEVNT_RR		(1 << 13)
 #define PSC_I2SEVNT_RO		(1 << 12)
 #define PSC_I2SEVNT_RU		(1 << 11)
@@ -305,8 +288,7 @@
 #define PSC_I2SEVNT_RD		(1 << 5)
 #define PSC_I2SEVNT_TD		(1 << 4)
 
-/* PSC in SPI Mode.
-*/
+/* PSC in SPI Mode. */
 typedef struct	psc_spi {
 	u32	psc_sel;
 	u32	psc_ctrl;
@@ -318,8 +300,7 @@
 	u32	psc_spitxrx;
 } psc_spi_t;
 
-/* SPI Config Register.
-*/
+/* SPI Config Register. */
 #define PSC_SPICFG_RT_MASK	(3 << 30)
 #define PSC_SPICFG_RT_FIFO1	(0 << 30)
 #define PSC_SPICFG_RT_FIFO2	(1 << 30)
@@ -355,8 +336,7 @@
 #define PSC_SPICFG_MLF		(1 << 1)
 #define PSC_SPICFG_MO		(1 << 0)
 
-/* SPI Mask Register.
-*/
+/* SPI Mask Register. */
 #define PSC_SPIMSK_MM		(1 << 16)
 #define PSC_SPIMSK_RR		(1 << 13)
 #define PSC_SPIMSK_RO		(1 << 12)
@@ -371,16 +351,14 @@
 				 PSC_SPIMSK_TU | PSC_SPIMSK_SD | \
 				 PSC_SPIMSK_MD)
 
-/* SPI Protocol Control Register.
-*/
+/* SPI Protocol Control Register. */
 #define PSC_SPIPCR_RC		(1 << 6)
 #define PSC_SPIPCR_SP		(1 << 5)
 #define PSC_SPIPCR_SS		(1 << 4)
 #define PSC_SPIPCR_TC		(1 << 2)
 #define PSC_SPIPCR_MS		(1 << 0)
 
-/* SPI Status register (read only).
-*/
+/* SPI Status register (read only). */
 #define PSC_SPISTAT_RF		(1 << 13)
 #define PSC_SPISTAT_RE		(1 << 12)
 #define PSC_SPISTAT_RR		(1 << 11)
@@ -393,8 +371,7 @@
 #define PSC_SPISTAT_DR		(1 << 1)
 #define PSC_SPISTAT_SR		(1 << 0)
 
-/* SPI Event Register.
-*/
+/* SPI Event Register. */
 #define PSC_SPIEVNT_MM		(1 << 16)
 #define PSC_SPIEVNT_RR		(1 << 13)
 #define PSC_SPIEVNT_RO		(1 << 12)
@@ -405,13 +382,11 @@
 #define PSC_SPIEVNT_SD		(1 << 5)
 #define PSC_SPIEVNT_MD		(1 << 4)
 
-/* Transmit register control.
-*/
+/* Transmit register control. */
 #define PSC_SPITXRX_LC		(1 << 29)
 #define PSC_SPITXRX_SR		(1 << 28)
 
-/* PSC in SMBus (I2C) Mode.
-*/
+/* PSC in SMBus (I2C) Mode. */
 typedef struct	psc_smb {
 	u32	psc_sel;
 	u32	psc_ctrl;
@@ -424,8 +399,7 @@
 	u32	psc_smbtmr;
 } psc_smb_t;
 
-/* SMBus Config Register.
-*/
+/* SMBus Config Register. */
 #define PSC_SMBCFG_RT_MASK	(3 << 30)
 #define PSC_SMBCFG_RT_FIFO1	(0 << 30)
 #define PSC_SMBCFG_RT_FIFO2	(1 << 30)
@@ -452,8 +426,7 @@
 
 #define PSC_SMBCFG_SET_SLV(x)	(((x) & 0x7f) << 1)
 
-/* SMBus Mask Register.
-*/
+/* SMBus Mask Register. */
 #define PSC_SMBMSK_DN		(1 << 30)
 #define PSC_SMBMSK_AN		(1 << 29)
 #define PSC_SMBMSK_AL		(1 << 28)
@@ -471,13 +444,11 @@
 				 PSC_SMBMSK_TU | PSC_SMBMSK_SD | \
 				 PSC_SMBMSK_MD)
 
-/* SMBus Protocol Control Register.
-*/
+/* SMBus Protocol Control Register. */
 #define PSC_SMBPCR_DC		(1 << 2)
 #define PSC_SMBPCR_MS		(1 << 0)
 
-/* SMBus Status register (read only).
-*/
+/* SMBus Status register (read only). */
 #define PSC_SMBSTAT_BB		(1 << 28)
 #define PSC_SMBSTAT_RF		(1 << 13)
 #define PSC_SMBSTAT_RE		(1 << 12)
@@ -491,8 +462,7 @@
 #define PSC_SMBSTAT_DR		(1 << 1)
 #define PSC_SMBSTAT_SR		(1 << 0)
 
-/* SMBus Event Register.
-*/
+/* SMBus Event Register. */
 #define PSC_SMBEVNT_DN		(1 << 30)
 #define PSC_SMBEVNT_AN		(1 << 29)
 #define PSC_SMBEVNT_AL		(1 << 28)
@@ -510,15 +480,13 @@
 				 PSC_SMBEVNT_TU | PSC_SMBEVNT_SD | \
 				 PSC_SMBEVNT_MD)
 
-/* Transmit register control.
-*/
+/* Transmit register control. */
 #define PSC_SMBTXRX_RSR		(1 << 28)
 #define PSC_SMBTXRX_STP		(1 << 29)
-#define PSC_SMBTXRX_DATAMASK	(0xff)
+#define PSC_SMBTXRX_DATAMASK	0xff
 
-/* SMBus protocol timers register.
-*/
-#define PSC_SMBTMR_SET_TH(x)	(((x) & 0x3) << 30)
+/* SMBus protocol timers register. */
+#define PSC_SMBTMR_SET_TH(x)	(((x) & 0x03) << 30)
 #define PSC_SMBTMR_SET_PS(x)	(((x) & 0x1f) << 25)
 #define PSC_SMBTMR_SET_PU(x)	(((x) & 0x1f) << 20)
 #define PSC_SMBTMR_SET_SH(x)	(((x) & 0x1f) << 15)
@@ -526,5 +494,4 @@
 #define PSC_SMBTMR_SET_CL(x)	(((x) & 0x1f) << 5)
 #define PSC_SMBTMR_SET_CH(x)	(((x) & 0x1f) << 0)
 
-
 #endif /* _AU1000_PSC_H_ */
diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h
index eedd048..27f2610 100644
--- a/include/asm-mips/mach-db1x00/db1200.h
+++ b/include/asm-mips/mach-db1x00/db1200.h
@@ -1,6 +1,6 @@
 /*
- * AMD Alchemy DB1200 Referrence Board
- * Board Registers defines.
+ * AMD Alchemy DBAu1200 Reference Board
+ * Board register defines.
  *
  * ########################################################################
  *
@@ -27,26 +27,25 @@
 #include <linux/types.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
-// This is defined in au1000.h with bogus value
-#undef AU1X00_EXTERNAL_INT
+#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC1_RX
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
-
-/* SPI and SMB are muxed on the Pb1200 board.
-   Refer to board documentation.
+/*
+ * SPI and SMB are muxed on the DBAu1200 board.
+ * Refer to board documentation.
  */
-#define SPI_PSC_BASE        PSC0_BASE_ADDR
-#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
-/* AC97 and I2S are muxed on the Pb1200 board.
-   Refer to board documentation.
+#define SPI_PSC_BASE		PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE		PSC0_BASE_ADDR
+/*
+ * AC'97 and I2S are muxed on the DBAu1200 board.
+ * Refer to board documentation.
  */
-#define AC97_PSC_BASE       PSC1_BASE_ADDR
+#define AC97_PSC_BASE		PSC1_BASE_ADDR
 #define I2S_PSC_BASE		PSC1_BASE_ADDR
 
-#define BCSR_KSEG1_ADDR 0xB9800000
+#define BCSR_KSEG1_ADDR 	0xB9800000
 
 typedef volatile struct
 {
@@ -102,9 +101,9 @@
 #define BCSR_STATUS_SWAPBOOT	0x0040
 #define BCSR_STATUS_FLASHBUSY	0x0100
 #define BCSR_STATUS_IDECBLID	0x0200
-#define BCSR_STATUS_SD0WP		0x0400
-#define BCSR_STATUS_U0RXD		0x1000
-#define BCSR_STATUS_U1RXD		0x2000
+#define BCSR_STATUS_SD0WP	0x0400
+#define BCSR_STATUS_U0RXD	0x1000
+#define BCSR_STATUS_U1RXD	0x2000
 
 #define BCSR_SWITCHES_OCTAL	0x00FF
 #define BCSR_SWITCHES_DIP_1	0x0080
@@ -122,8 +121,8 @@
 #define BCSR_RESETS_DC		0x0004
 #define BCSR_RESETS_IDE		0x0008
 #define BCSR_RESETS_TV		0x0010
-/* not resets but in the same register */
-#define BCSR_RESETS_PWMR1mUX 0x0800
+/* Not resets but in the same register */
+#define BCSR_RESETS_PWMR1MUX	0x0800
 #define BCSR_RESETS_PCS0MUX	0x1000
 #define BCSR_RESETS_PCS1MUX	0x2000
 #define BCSR_RESETS_SPISEL	0x4000
@@ -160,7 +159,7 @@
 #define BCSR_INT_PC0STSCHG	0x0008
 #define BCSR_INT_PC1		0x0010
 #define BCSR_INT_PC1STSCHG	0x0020
-#define BCSR_INT_DC			0x0040
+#define BCSR_INT_DC		0x0040
 #define BCSR_INT_FLASHBUSY	0x0080
 #define BCSR_INT_PC0INSERT	0x0100
 #define BCSR_INT_PC0EJECT	0x0200
@@ -179,10 +178,10 @@
 #define IDE_DDMA_REQ		DSCR_CMD0_DMA_REQ1
 #define IDE_RQSIZE		128
 
-#define NAND_PHYS_ADDR   0x20000000
+#define NAND_PHYS_ADDR		0x20000000
 
 /*
- * External Interrupts for Pb1200 as of 8/6/2004.
+ * External Interrupts for DBAu1200 as of 8/6/2004.
  * Bit positions in the CPLD registers can be calculated by taking
  * the interrupt define and subtracting the DB1200_INT_BEGIN value.
  *
@@ -211,23 +210,21 @@
 };
 
 
-/* For drivers/pcmcia/au1000_db1x00.c */
-
-/* PCMCIA Db1x00 specific defines */
-
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/*
+ * DBAu1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
+ */
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 
-#define BOARD_PC0_INT DB1200_PC0_INT
-#define BOARD_PC1_INT DB1200_PC1_INT
-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+#define BOARD_PC0_INT	DB1200_PC0_INT
+#define BOARD_PC1_INT	DB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
 
-/* Nand chip select */
+/* NAND chip select */
 #define NAND_CS 1
 
 #endif /* __ASM_DB1200_H */
-
diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h
index e7a88ba..612ae90 100644
--- a/include/asm-mips/mach-db1x00/db1x00.h
+++ b/include/asm-mips/mach-db1x00/db1x00.h
@@ -1,9 +1,8 @@
 /*
- * AMD Alchemy DB1x00 Reference Boards
+ * AMD Alchemy DBAu1x00 Reference Boards
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  * ########################################################################
@@ -32,26 +31,26 @@
 
 #ifdef CONFIG_MIPS_DB1550
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN  DSCR_CMD0_PSC3_TX
-#define DBDMA_I2S_RX_CHAN  DSCR_CMD0_PSC3_RX
+#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC3_RX
 
-#define SPI_PSC_BASE       PSC0_BASE_ADDR
-#define AC97_PSC_BASE      PSC1_BASE_ADDR
-#define SMBUS_PSC_BASE     PSC2_BASE_ADDR
-#define I2S_PSC_BASE       PSC3_BASE_ADDR
+#define SPI_PSC_BASE		PSC0_BASE_ADDR
+#define AC97_PSC_BASE		PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE		PSC2_BASE_ADDR
+#define I2S_PSC_BASE		PSC3_BASE_ADDR
 
-#define BCSR_KSEG1_ADDR 0xAF000000
-#define NAND_PHYS_ADDR  0x20000000
+#define BCSR_KSEG1_ADDR 	0xAF000000
+#define NAND_PHYS_ADDR		0x20000000
 
 #else
 #define BCSR_KSEG1_ADDR 0xAE000000
 #endif
 
 /*
- * Overlay data structure of the Db1x00 board registers.
- * Registers located at physical 0E0000xx, KSEG1 0xAE0000xx
+ * Overlay data structure of the DBAu1x00 board registers.
+ * Registers are located at physical 0E0000xx, KSEG1 0xAE0000xx.
  */
 typedef volatile struct
 {
@@ -138,18 +137,19 @@
 
 #define BCSR_SWRESET_RESET		0x0080
 
-/* PCMCIA Db1x00 specific defines */
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/* PCMCIA DBAu1x00 specific defines */
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
 #define SET_VCC_VPP(VCC, VPP, SLOT)\
-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 
-/* SD controller macros */
 /*
- * Detect card.
+ * SD controller macros
  */
+
+/* Detect card. */
 #define mmc_card_inserted(_n_, _res_) \
 	do { \
 		BCSR * const bcsr = (BCSR *)0xAE000000; \
@@ -176,10 +176,10 @@
 		unsigned long mmc_pwr, mmc_wp, board_specific; \
 		if ((_n_)) { \
 			mmc_pwr = BCSR_BOARD_SD1_PWR; \
-			mmc_wp = BCSR_BOARD_SD1_WP; \
+			mmc_wp	= BCSR_BOARD_SD1_WP; \
 		} else { \
 			mmc_pwr = BCSR_BOARD_SD0_PWR; \
-			mmc_wp = BCSR_BOARD_SD0_WP; \
+			mmc_wp	= BCSR_BOARD_SD0_WP; \
 		} \
 		board_specific = au_readl((unsigned long)(&bcsr->specific)); \
 		if (!(board_specific & mmc_wp)) {/* low means card present */ \
@@ -190,17 +190,19 @@
 	} while (0)
 
 
-/* NAND defines */
-/* Timing values as described in databook, * ns value stripped of
+/*
+ * NAND defines
+ *
+ * Timing values as described in databook, * ns value stripped of the
  * lower 2 bits.
- * These defines are here rather than an SOC1550 generic file because
+ * These defines are here rather than an Au1550 generic file because
  * the parts chosen on another board may be different and may require
  * different timings.
  */
-#define NAND_T_H			(18 >> 2)
-#define NAND_T_PUL			(30 >> 2)
-#define NAND_T_SU			(30 >> 2)
-#define NAND_T_WH			(30 >> 2)
+#define NAND_T_H		(18 >> 2)
+#define NAND_T_PUL		(30 >> 2)
+#define NAND_T_SU		(30 >> 2)
+#define NAND_T_WH		(30 >> 2)
 
 /* Bitfield shift amounts */
 #define NAND_T_H_SHIFT		0
@@ -208,16 +210,15 @@
 #define NAND_T_SU_SHIFT		8
 #define NAND_T_WH_SHIFT		12
 
-#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
-			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
-			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
-			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
-#define NAND_CS 1
+#define NAND_TIMING	(((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
+			 ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+			 ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
+			 ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
+#define NAND_CS 	1
 
-/* should be done by yamon */
-#define NAND_STCFG  0x00400005 /* 8-bit NAND */
-#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */
-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
+/* Should be done by YAMON */
+#define NAND_STCFG	0x00400005 /* 8-bit NAND */
+#define NAND_STTIME	0x00007774 /* valid for 396 MHz SD=2 only */
+#define NAND_STADDR	0x12000FFF /* physical address 0x20000000 */
 
 #endif /* __ASM_DB1X00_H */
-
diff --git a/include/asm-mips/mach-pb1x00/pb1000.h b/include/asm-mips/mach-pb1x00/pb1000.h
index b52e0e7..6d1ff90 100644
--- a/include/asm-mips/mach-pb1x00/pb1000.h
+++ b/include/asm-mips/mach-pb1x00/pb1000.h
@@ -1,9 +1,8 @@
 /*
- * Alchemy Semi PB1000 Referrence Board
+ * Alchemy Semi Pb1000 Referrence Board
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * ########################################################################
  *
@@ -28,145 +27,61 @@
 #define __ASM_PB1000_H
 
 /* PCMCIA PB1000 specific defines */
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
-#define PB1000_PCR     0xBE000000
-#  define PCR_SLOT_0_VPP0  (1<<0)
-#  define PCR_SLOT_0_VPP1  (1<<1)
-#  define PCR_SLOT_0_VCC0  (1<<2)
-#  define PCR_SLOT_0_VCC1  (1<<3)
-#  define PCR_SLOT_0_RST   (1<<4)
+#define PB1000_PCR		0xBE000000
+#  define PCR_SLOT_0_VPP0	(1 << 0)
+#  define PCR_SLOT_0_VPP1	(1 << 1)
+#  define PCR_SLOT_0_VCC0	(1 << 2)
+#  define PCR_SLOT_0_VCC1	(1 << 3)
+#  define PCR_SLOT_0_RST	(1 << 4)
+#  define PCR_SLOT_1_VPP0	(1 << 8)
+#  define PCR_SLOT_1_VPP1	(1 << 9)
+#  define PCR_SLOT_1_VCC0	(1 << 10)
+#  define PCR_SLOT_1_VCC1	(1 << 11)
+#  define PCR_SLOT_1_RST	(1 << 12)
 
-#  define PCR_SLOT_1_VPP0  (1<<8)
-#  define PCR_SLOT_1_VPP1  (1<<9)
-#  define PCR_SLOT_1_VCC0  (1<<10)
-#  define PCR_SLOT_1_VCC1  (1<<11)
-#  define PCR_SLOT_1_RST   (1<<12)
+#define PB1000_MDR		0xBE000004
+#  define MDR_PI		(1 << 5)	/* PCMCIA int latch  */
+#  define MDR_EPI		(1 << 14)	/* enable PCMCIA int */
+#  define MDR_CPI		(1 << 15)	/* clear  PCMCIA int  */
 
-#define PB1000_MDR     0xBE000004
-#  define MDR_PI        (1<<5)  /* pcmcia int latch  */
-#  define MDR_EPI      (1<<14)  /* enable pcmcia int */
-#  define MDR_CPI      (1<<15)  /* clear pcmcia int  */
+#define PB1000_ACR1		0xBE000008
+#  define ACR1_SLOT_0_CD1	(1 << 0)	/* card detect 1	*/
+#  define ACR1_SLOT_0_CD2	(1 << 1)	/* card detect 2	*/
+#  define ACR1_SLOT_0_READY	(1 << 2)	/* ready		*/
+#  define ACR1_SLOT_0_STATUS	(1 << 3)	/* status change	*/
+#  define ACR1_SLOT_0_VS1	(1 << 4)	/* voltage sense 1	*/
+#  define ACR1_SLOT_0_VS2	(1 << 5)	/* voltage sense 2	*/
+#  define ACR1_SLOT_0_INPACK	(1 << 6)	/* inpack pin status	*/
+#  define ACR1_SLOT_1_CD1	(1 << 8)	/* card detect 1	*/
+#  define ACR1_SLOT_1_CD2	(1 << 9)	/* card detect 2	*/
+#  define ACR1_SLOT_1_READY	(1 << 10)	/* ready		*/
+#  define ACR1_SLOT_1_STATUS	(1 << 11)	/* status change	*/
+#  define ACR1_SLOT_1_VS1	(1 << 12)	/* voltage sense 1	*/
+#  define ACR1_SLOT_1_VS2	(1 << 13)	/* voltage sense 2	*/
+#  define ACR1_SLOT_1_INPACK	(1 << 14)	/* inpack pin status	*/
 
-#define PB1000_ACR1    0xBE000008
-#  define ACR1_SLOT_0_CD1    (1<<0)  /* card detect 1     */
-#  define ACR1_SLOT_0_CD2    (1<<1)  /* card detect 2     */
-#  define ACR1_SLOT_0_READY  (1<<2)  /* ready             */
-#  define ACR1_SLOT_0_STATUS (1<<3)  /* status change     */
-#  define ACR1_SLOT_0_VS1    (1<<4)  /* voltage sense 1   */
-#  define ACR1_SLOT_0_VS2    (1<<5)  /* voltage sense 2   */
-#  define ACR1_SLOT_0_INPACK (1<<6)  /* inpack pin status */
-#  define ACR1_SLOT_1_CD1    (1<<8)  /* card detect 1     */
-#  define ACR1_SLOT_1_CD2    (1<<9)  /* card detect 2     */
-#  define ACR1_SLOT_1_READY  (1<<10) /* ready             */
-#  define ACR1_SLOT_1_STATUS (1<<11) /* status change     */
-#  define ACR1_SLOT_1_VS1    (1<<12) /* voltage sense 1   */
-#  define ACR1_SLOT_1_VS2    (1<<13) /* voltage sense 2   */
-#  define ACR1_SLOT_1_INPACK (1<<14) /* inpack pin status */
-
-#define CPLD_AUX0      0xBE00000C
-#define CPLD_AUX1      0xBE000010
-#define CPLD_AUX2      0xBE000014
+#define CPLD_AUX0		0xBE00000C
+#define CPLD_AUX1		0xBE000010
+#define CPLD_AUX2		0xBE000014
 
 /* Voltage levels */
 
 /* VPPEN1 - VPPEN0 */
-#define VPP_GND ((0<<1) | (0<<0))
-#define VPP_5V  ((1<<1) | (0<<0))
-#define VPP_3V  ((0<<1) | (1<<0))
-#define VPP_12V ((0<<1) | (1<<0))
-#define VPP_HIZ ((1<<1) | (1<<0))
+#define VPP_GND ((0 << 1) | (0 << 0))
+#define VPP_5V	((1 << 1) | (0 << 0))
+#define VPP_3V	((0 << 1) | (1 << 0))
+#define VPP_12V ((0 << 1) | (1 << 0))
+#define VPP_HIZ ((1 << 1) | (1 << 0))
 
 /* VCCEN1 - VCCEN0 */
-#define VCC_3V  ((0<<1) | (1<<0))
-#define VCC_5V  ((1<<1) | (0<<0))
-#define VCC_HIZ ((0<<1) | (0<<0))
+#define VCC_3V	((0 << 1) | (1 << 0))
+#define VCC_5V	((1 << 1) | (0 << 0))
+#define VCC_HIZ ((0 << 1) | (0 << 0))
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
-
-
-/* PCI PB1000 specific defines */
-/* The reason these defines are here instead of au1000.h is because
- * the Au1000 does not have a PCI bus controller so the PCI implementation
- * on the some of the older Pb1000 boards was very board specific.
- */
-#define PCI_CONFIG_BASE   0xBA020000 /* the only external slot */
-
-#define SDRAM_DEVID       0xBA010000
-#define SDRAM_CMD         0xBA010004
-#define SDRAM_CLASS       0xBA010008
-#define SDRAM_MISC        0xBA01000C
-#define SDRAM_MBAR        0xBA010010
-
-#define PCI_IO_DATA_PORT  0xBA800000
-
-#define PCI_IO_ADDR       0xBE00001C
-#define PCI_INT_ACK       0xBBC00000
-#define PCI_IO_READ       0xBBC00020
-#define PCI_IO_WRITE      0xBBC00030
-
-#define PCI_BRIDGE_CONFIG 0xBE000018
-
-#define PCI_IO_START      0x10000000
-#define PCI_IO_END        0x1000ffff
-#define PCI_MEM_START     0x18000000
-#define PCI_MEM_END       0x18ffffff
-
-#define PCI_FIRST_DEVFN   0
-#define PCI_LAST_DEVFN    1
-
-static inline u8 au_pci_io_readb(u32 addr)
-{
-	writel(addr, PCI_IO_ADDR);
-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
-	return (readl(PCI_IO_DATA_PORT) & 0xff);
-}
-
-static inline u16 au_pci_io_readw(u32 addr)
-{
-	writel(addr, PCI_IO_ADDR);
-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
-	return (readl(PCI_IO_DATA_PORT) & 0xffff);
-}
-
-static inline u32 au_pci_io_readl(u32 addr)
-{
-	writel(addr, PCI_IO_ADDR);
-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff), PCI_BRIDGE_CONFIG);
-	return readl(PCI_IO_DATA_PORT);
-}
-
-static inline void au_pci_io_writeb(u8 val, u32 addr)
-{
-	writel(addr, PCI_IO_ADDR);
-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG);
-	writel(val, PCI_IO_DATA_PORT);
-}
-
-static inline void au_pci_io_writew(u16 val, u32 addr)
-{
-	writel(addr, PCI_IO_ADDR);
-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG);
-	writel(val, PCI_IO_DATA_PORT);
-}
-
-static inline void au_pci_io_writel(u32 val, u32 addr)
-{
-	writel(addr, PCI_IO_ADDR);
-	writel(readl(PCI_BRIDGE_CONFIG) & 0xffffcfff, PCI_BRIDGE_CONFIG);
-	writel(val, PCI_IO_DATA_PORT);
-}
-
-static inline void set_sdram_extbyte(void)
-{
-	writel(readl(PCI_BRIDGE_CONFIG) & 0xffffff00, PCI_BRIDGE_CONFIG);
-}
-
-static inline void set_slot_extbyte(void)
-{
-	writel((readl(PCI_BRIDGE_CONFIG) & 0xffffbf00) | 0x18, PCI_BRIDGE_CONFIG);
-}
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 #endif /* __ASM_PB1000_H */
diff --git a/include/asm-mips/mach-pb1x00/pb1100.h b/include/asm-mips/mach-pb1x00/pb1100.h
index 63aa392..b1a60f1 100644
--- a/include/asm-mips/mach-pb1x00/pb1100.h
+++ b/include/asm-mips/mach-pb1x00/pb1100.h
@@ -1,9 +1,8 @@
 /*
- * Alchemy Semi PB1100 Referrence Board
+ * Alchemy Semi Pb1100 Referrence Board
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * ########################################################################
  *
@@ -27,59 +26,60 @@
 #ifndef __ASM_PB1100_H
 #define __ASM_PB1100_H
 
-#define PB1100_IDENT          0xAE000000
-#define BOARD_STATUS_REG      0xAE000004
-#  define PB1100_ROM_SEL         (1<<15)
-#  define PB1100_ROM_SIZ         (1<<14)
-#  define PB1100_SWAP_BOOT       (1<<13)
-#  define PB1100_FLASH_WP        (1<<12)
-#  define PB1100_ROM_H_STS       (1<<11)
-#  define PB1100_ROM_L_STS       (1<<10)
-#  define PB1100_FLASH_H_STS      (1<<9)
-#  define PB1100_FLASH_L_STS      (1<<8)
-#  define PB1100_SRAM_SIZ         (1<<7)
-#  define PB1100_TSC_BUSY         (1<<6)
-#  define PB1100_PCMCIA_VS_MASK   (3<<4)
-#  define PB1100_RS232_CD         (1<<3)
-#  define PB1100_RS232_CTS        (1<<2)
-#  define PB1100_RS232_DSR        (1<<1)
-#  define PB1100_RS232_RI         (1<<0)
+#define PB1100_IDENT		0xAE000000
+#define BOARD_STATUS_REG	0xAE000004
+#  define PB1100_ROM_SEL	(1 << 15)
+#  define PB1100_ROM_SIZ	(1 << 14)
+#  define PB1100_SWAP_BOOT	(1 << 13)
+#  define PB1100_FLASH_WP	(1 << 12)
+#  define PB1100_ROM_H_STS	(1 << 11)
+#  define PB1100_ROM_L_STS	(1 << 10)
+#  define PB1100_FLASH_H_STS	(1 << 9)
+#  define PB1100_FLASH_L_STS	(1 << 8)
+#  define PB1100_SRAM_SIZ	(1 << 7)
+#  define PB1100_TSC_BUSY	(1 << 6)
+#  define PB1100_PCMCIA_VS_MASK (3 << 4)
+#  define PB1100_RS232_CD	(1 << 3)
+#  define PB1100_RS232_CTS	(1 << 2)
+#  define PB1100_RS232_DSR	(1 << 1)
+#  define PB1100_RS232_RI	(1 << 0)
 
-#define PB1100_IRDA_RS232     0xAE00000C
-#  define PB1100_IRDA_FULL       (0<<14) /* full power */
-#  define PB1100_IRDA_SHUTDOWN   (1<<14)
-#  define PB1100_IRDA_TT         (2<<14) /* 2/3 power */
-#  define PB1100_IRDA_OT         (3<<14) /* 1/3 power */
-#  define PB1100_IRDA_FIR        (1<<13)
+#define PB1100_IRDA_RS232	0xAE00000C
+#  define PB1100_IRDA_FULL	(0 << 14)	/* full power		*/
+#  define PB1100_IRDA_SHUTDOWN	(1 << 14)
+#  define PB1100_IRDA_TT	(2 << 14)	/* 2/3 power		*/
+#  define PB1100_IRDA_OT	(3 << 14)	/* 1/3 power		*/
+#  define PB1100_IRDA_FIR	(1 << 13)
 
-#define PCMCIA_BOARD_REG     0xAE000010
-#  define PB1100_SD_WP1_RO       (1<<15) /* read only */
-#  define PB1100_SD_WP0_RO       (1<<14) /* read only */
-#  define PB1100_SD_PWR1         (1<<11) /* applies power to SD1 */
-#  define PB1100_SD_PWR0         (1<<10) /* applies power to SD0 */
-#  define PB1100_SEL_SD_CONN1     (1<<9)
-#  define PB1100_SEL_SD_CONN0     (1<<8)
-#  define PC_DEASSERT_RST         (1<<7)
-#  define PC_DRV_EN               (1<<4)
+#define PCMCIA_BOARD_REG	0xAE000010
+#  define PB1100_SD_WP1_RO	(1 << 15)	/* read only		*/
+#  define PB1100_SD_WP0_RO	(1 << 14)	/* read only		*/
+#  define PB1100_SD_PWR1	(1 << 11)	/* applies power to SD1 */
+#  define PB1100_SD_PWR0	(1 << 10)	/* applies power to SD0 */
+#  define PB1100_SEL_SD_CONN1	(1 << 9)
+#  define PB1100_SEL_SD_CONN0	(1 << 8)
+#  define PC_DEASSERT_RST	(1 << 7)
+#  define PC_DRV_EN		(1 << 4)
 
-#define PB1100_G_CONTROL      0xAE000014 /* graphics control */
+#define PB1100_G_CONTROL	0xAE000014	/* graphics control	*/
 
-#define PB1100_RST_VDDI       0xAE00001C
-#  define PB1100_SOFT_RESET      (1<<15) /* clear to reset the board */
-#  define PB1100_VDDI_MASK        (0x1F)
+#define PB1100_RST_VDDI 	0xAE00001C
+#  define PB1100_SOFT_RESET	(1 << 15)	/* clear to reset the board */
+#  define PB1100_VDDI_MASK	0x1F
 
-#define PB1100_LEDS           0xAE000018
+#define PB1100_LEDS		0xAE000018
 
-/* 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
- * 7:0 is the LED Display's decimal points.
+/*
+ * 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
+ * 7:0  is the LED Display's decimal points.
  */
-#define PB1100_HEX_LED        0xAE000018
+#define PB1100_HEX_LED		0xAE000018
 
-/* PCMCIA PB1100 specific defines */
-#define PCMCIA_MAX_SOCK 0
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/* PCMCIA Pb1100 specific defines */
+#define PCMCIA_MAX_SOCK  0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
+#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
 
 #endif /* __ASM_PB1100_H */
diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h
index e2c6bca..c8618df 100644
--- a/include/asm-mips/mach-pb1x00/pb1200.h
+++ b/include/asm-mips/mach-pb1x00/pb1200.h
@@ -1,5 +1,5 @@
 /*
- * AMD Alchemy PB1200 Referrence Board
+ * AMD Alchemy Pb1200 Referrence Board
  * Board Registers defines.
  *
  * ########################################################################
@@ -27,21 +27,20 @@
 #include <linux/types.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
-// This is defined in au1000.h with bogus value
-#undef AU1X00_EXTERNAL_INT
+#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC1_RX
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
-
-/* SPI and SMB are muxed on the Pb1200 board.
-   Refer to board documentation.
+/*
+ * SPI and SMB are muxed on the Pb1200 board.
+ * Refer to board documentation.
  */
-#define SPI_PSC_BASE        PSC0_BASE_ADDR
-#define SMBUS_PSC_BASE      PSC0_BASE_ADDR
-/* AC97 and I2S are muxed on the Pb1200 board.
-   Refer to board documentation.
+#define SPI_PSC_BASE		PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE		PSC0_BASE_ADDR
+/*
+ * AC97 and I2S are muxed on the Pb1200 board.
+ * Refer to board documentation.
  */
 #define AC97_PSC_BASE       PSC1_BASE_ADDR
 #define I2S_PSC_BASE		PSC1_BASE_ADDR
@@ -102,10 +101,10 @@
 #define BCSR_STATUS_SWAPBOOT	0x0040
 #define BCSR_STATUS_FLASHBUSY	0x0100
 #define BCSR_STATUS_IDECBLID	0x0200
-#define BCSR_STATUS_SD0WP		0x0400
-#define BCSR_STATUS_SD1WP		0x0800
-#define BCSR_STATUS_U0RXD		0x1000
-#define BCSR_STATUS_U1RXD		0x2000
+#define BCSR_STATUS_SD0WP	0x0400
+#define BCSR_STATUS_SD1WP	0x0800
+#define BCSR_STATUS_U0RXD	0x1000
+#define BCSR_STATUS_U1RXD	0x2000
 
 #define BCSR_SWITCHES_OCTAL	0x00FF
 #define BCSR_SWITCHES_DIP_1	0x0080
@@ -123,11 +122,11 @@
 #define BCSR_RESETS_DC		0x0004
 #define BCSR_RESETS_IDE		0x0008
 /* not resets but in the same register */
-#define BCSR_RESETS_WSCFSM  0x0800
+#define BCSR_RESETS_WSCFSM	0x0800
 #define BCSR_RESETS_PCS0MUX	0x1000
 #define BCSR_RESETS_PCS1MUX	0x2000
 #define BCSR_RESETS_SPISEL	0x4000
-#define BCSR_RESETS_SD1MUX  0x8000
+#define BCSR_RESETS_SD1MUX	0x8000
 
 #define BCSR_PCMCIA_PC0VPP	0x0003
 #define BCSR_PCMCIA_PC0VCC	0x000C
@@ -163,7 +162,7 @@
 #define BCSR_INT_PC0STSCHG	0x0008
 #define BCSR_INT_PC1		0x0010
 #define BCSR_INT_PC1STSCHG	0x0020
-#define BCSR_INT_DC			0x0040
+#define BCSR_INT_DC		0x0040
 #define BCSR_INT_FLASHBUSY	0x0080
 #define BCSR_INT_PC0INSERT	0x0100
 #define BCSR_INT_PC0EJECT	0x0200
@@ -174,14 +173,6 @@
 #define BCSR_INT_SD1INSERT	0x4000
 #define BCSR_INT_SD1EJECT	0x8000
 
-/* PCMCIA Db1x00 specific defines */
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
-
 #define SMC91C111_PHYS_ADDR	0x0D000300
 #define SMC91C111_INT		PB1200_ETH_INT
 
@@ -192,18 +183,19 @@
 #define IDE_DDMA_REQ		DSCR_CMD0_DMA_REQ1
 #define IDE_RQSIZE		128
 
-#define NAND_PHYS_ADDR   0x1C000000
+#define NAND_PHYS_ADDR 	0x1C000000
 
-/* Timing values as described in databook, * ns value stripped of
+/*
+ * Timing values as described in databook, * ns value stripped of
  * lower 2 bits.
- * These defines are here rather than an SOC1200 generic file because
+ * These defines are here rather than an Au1200 generic file because
  * the parts chosen on another board may be different and may require
  * different timings.
  */
-#define NAND_T_H			(18 >> 2)
-#define NAND_T_PUL			(30 >> 2)
-#define NAND_T_SU			(30 >> 2)
-#define NAND_T_WH			(30 >> 2)
+#define NAND_T_H		(18 >> 2)
+#define NAND_T_PUL		(30 >> 2)
+#define NAND_T_SU		(30 >> 2)
+#define NAND_T_WH		(30 >> 2)
 
 /* Bitfield shift amounts */
 #define NAND_T_H_SHIFT		0
@@ -211,11 +203,10 @@
 #define NAND_T_SU_SHIFT		8
 #define NAND_T_WH_SHIFT		12
 
-#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
-			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
-			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
-			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
-
+#define NAND_TIMING	(((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
+			 ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+			 ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
+			 ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
 
 /*
  * External Interrupts for Pb1200 as of 8/6/2004.
@@ -248,13 +239,21 @@
 	PB1200_INT_END		= PB1200_INT_BEGIN + 15
 };
 
-/* For drivers/pcmcia/au1000_db1x00.c */
-#define BOARD_PC0_INT PB1200_PC0_INT
-#define BOARD_PC1_INT PB1200_PC1_INT
-#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1<<(8+(2*SOCKET)))
+/*
+ * Pb1200 specific PCMCIA defines for drivers/pcmcia/au1000_db1x00.c
+ */
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
-/* Nand chip select */
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+
+#define BOARD_PC0_INT	PB1200_PC0_INT
+#define BOARD_PC1_INT	PB1200_PC1_INT
+#define BOARD_CARD_INSERTED(SOCKET) bcsr->sig_status & (1 << (8 + (2 * SOCKET)))
+
+/* NAND chip select */
 #define NAND_CS 1
 
 #endif /* __ASM_PB1200_H */
-
diff --git a/include/asm-mips/mach-pb1x00/pb1500.h b/include/asm-mips/mach-pb1x00/pb1500.h
index ff6d40c..da51a2e 100644
--- a/include/asm-mips/mach-pb1x00/pb1500.h
+++ b/include/asm-mips/mach-pb1x00/pb1500.h
@@ -1,9 +1,8 @@
 /*
- * Alchemy Semi PB1500 Referrence Board
+ * Alchemy Semi Pb1500 Referrence Board
  *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
  *
  * ########################################################################
  *
@@ -27,25 +26,24 @@
 #ifndef __ASM_PB1500_H
 #define __ASM_PB1500_H
 
+#define IDENT_BOARD_REG 	0xAE000000
+#define BOARD_STATUS_REG	0xAE000004
+#define PCI_BOARD_REG		0xAE000010
+#define PCMCIA_BOARD_REG	0xAE000010
+#  define PC_DEASSERT_RST	      0x80
+#  define PC_DRV_EN		      0x10
+#define PB1500_G_CONTROL	0xAE000014
+#define PB1500_RST_VDDI 	0xAE00001C
+#define PB1500_LEDS		0xAE000018
 
-#define IDENT_BOARD_REG           0xAE000000
-#define BOARD_STATUS_REG          0xAE000004
-#define PCI_BOARD_REG             0xAE000010
-#define PCMCIA_BOARD_REG          0xAE000010
-  #define PC_DEASSERT_RST               0x80
-  #define PC_DRV_EN                     0x10
-#define PB1500_G_CONTROL          0xAE000014
-#define PB1500_RST_VDDI           0xAE00001C
-#define PB1500_LEDS               0xAE000018
+#define PB1500_HEX_LED		0xAF000004
+#define PB1500_HEX_LED_BLANK	0xAF000008
 
-#define PB1500_HEX_LED            0xAF000004
-#define PB1500_HEX_LED_BLANK      0xAF000008
-
-/* PCMCIA PB1500 specific defines */
-#define PCMCIA_MAX_SOCK 0
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+/* PCMCIA Pb1500 specific defines */
+#define PCMCIA_MAX_SOCK  0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
+#define SET_VCC_VPP(VCC, VPP) (((VCC) << 2) | ((VPP) << 0))
 
 #endif /* __ASM_PB1500_H */
diff --git a/include/asm-mips/mach-pb1x00/pb1550.h b/include/asm-mips/mach-pb1x00/pb1550.h
index c2ab0e2..6704a11 100644
--- a/include/asm-mips/mach-pb1x00/pb1550.h
+++ b/include/asm-mips/mach-pb1x00/pb1550.h
@@ -30,15 +30,15 @@
 #include <linux/types.h>
 #include <asm/mach-au1x00/au1xxx_psc.h>
 
-#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX
-#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX
+#define DBDMA_AC97_TX_CHAN	DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN	DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN	DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN	DSCR_CMD0_PSC3_RX
 
-#define SPI_PSC_BASE        PSC0_BASE_ADDR
-#define AC97_PSC_BASE       PSC1_BASE_ADDR
-#define SMBUS_PSC_BASE      PSC2_BASE_ADDR
-#define I2S_PSC_BASE        PSC3_BASE_ADDR
+#define SPI_PSC_BASE		PSC0_BASE_ADDR
+#define AC97_PSC_BASE		PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE		PSC2_BASE_ADDR
+#define I2S_PSC_BASE		PSC3_BASE_ADDR
 
 #define BCSR_PHYS_ADDR 0xAF000000
 
@@ -129,12 +129,12 @@
 #define BCSR_SYSTEM_POWEROFF	0x4000
 #define BCSR_SYSTEM_RESET	0x8000
 
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+#define PCMCIA_MAX_SOCK  1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
 
 /* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT)\
-	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+	((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
 
 #if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
 #define PB1550_BOTH_BANKS
@@ -144,16 +144,17 @@
 #define PB1550_USER_ONLY
 #endif
 
-/* Timing values as described in databook, * ns value stripped of
+/*
+ * Timing values as described in databook, * ns value stripped of
  * lower 2 bits.
  * These defines are here rather than an SOC1550 generic file because
  * the parts chosen on another board may be different and may require
  * different timings.
  */
-#define NAND_T_H			(18 >> 2)
-#define NAND_T_PUL			(30 >> 2)
-#define NAND_T_SU			(30 >> 2)
-#define NAND_T_WH			(30 >> 2)
+#define NAND_T_H		(18 >> 2)
+#define NAND_T_PUL		(30 >> 2)
+#define NAND_T_SU		(30 >> 2)
+#define NAND_T_WH		(30 >> 2)
 
 /* Bitfield shift amounts */
 #define NAND_T_H_SHIFT		0
@@ -161,16 +162,16 @@
 #define NAND_T_SU_SHIFT		8
 #define NAND_T_WH_SHIFT		12
 
-#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
-			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
-			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
-			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
+#define NAND_TIMING	(((NAND_T_H   & 0xF) << NAND_T_H_SHIFT)   | \
+			 ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+			 ((NAND_T_SU  & 0xF) << NAND_T_SU_SHIFT)  | \
+			 ((NAND_T_WH  & 0xF) << NAND_T_WH_SHIFT))
 
 #define NAND_CS 1
 
-/* should be done by yamon */
-#define NAND_STCFG  0x00400005 /* 8-bit NAND */
-#define NAND_STTIME 0x00007774 /* valid for 396MHz SD=2 only */
-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
+/* Should be done by YAMON */
+#define NAND_STCFG	0x00400005 /* 8-bit NAND */
+#define NAND_STTIME	0x00007774 /* valid for 396 MHz SD=2 only */
+#define NAND_STADDR	0x12000FFF /* physical address 0x20000000 */
 
 #endif /* __ASM_PB1550_H */
diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h
index 65778c8..20b6660 100644
--- a/include/asm-mips/rtlx.h
+++ b/include/asm-mips/rtlx.h
@@ -29,13 +29,13 @@
 extern unsigned int rtlx_write_poll(int index);
 
 enum rtlx_state {
-	RTLX_STATE_UNUSED,
+	RTLX_STATE_UNUSED = 0,
 	RTLX_STATE_INITIALISED,
 	RTLX_STATE_REMOTE_READY,
 	RTLX_STATE_OPENED
 };
 
-#define RTLX_BUFFER_SIZE 1024
+#define RTLX_BUFFER_SIZE 2048
 
 /* each channel supports read and write.
    linux (vpe0) reads lx_buffer  and writes rt_buffer
diff --git a/include/asm-mn10300/processor.h b/include/asm-mn10300/processor.h
index f1b081f..7323927 100644
--- a/include/asm-mn10300/processor.h
+++ b/include/asm-mn10300/processor.h
@@ -58,7 +58,7 @@
 extern void identify_cpu(struct mn10300_cpuinfo *);
 extern void print_cpu_info(struct mn10300_cpuinfo *);
 extern void dodgy_tsc(void);
-#define cpu_relax() do {} while (0)
+#define cpu_relax() barrier()
 
 /*
  * User space process size: 1.75GB (default).
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index afae069..e0062d7 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -2,7 +2,7 @@
 #define _ASM_POWERPC_IO_H
 #ifdef __KERNEL__
 
-/* 
+/*
  * 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
@@ -18,6 +18,9 @@
 #define _PNPWRP		0xa79
 #define PNPBIOS_BASE	0xf000
 
+#include <linux/device.h>
+#include <linux/io.h>
+
 #include <linux/compiler.h>
 #include <asm/page.h>
 #include <asm/byteorder.h>
@@ -744,6 +747,9 @@
 
 #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
 
+void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
+				size_t size, unsigned long flags);
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_POWERPC_IO_H */
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h
index 7c97b5a..c08e714 100644
--- a/include/asm-powerpc/pgtable-ppc32.h
+++ b/include/asm-powerpc/pgtable-ppc32.h
@@ -209,6 +209,13 @@
  *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
  *   -  -  -  -  -    - U0 U1 U2 U3 W  I  M  G  E   - UX UW UR SX SW SR
  *
+ * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
+ * TLB2 storage attibute fields. Those are:
+ *
+ *   TLB2:
+ *   0...10    11   12   13   14   15   16...31
+ *   no change WL1  IL1I IL1D IL2I IL2D no change
+ *
  * There are some constrains and options, to decide mapping software bits
  * into TLB entry.
  *
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index e3c845b..6abead6 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -100,6 +100,7 @@
 
 /* Flag indicating progress during context switch. */
 #define SPU_CONTEXT_SWITCH_PENDING	0UL
+#define SPU_CONTEXT_FAULT_PENDING	1UL
 
 struct spu_context;
 struct spu_runqueue;
@@ -128,9 +129,11 @@
 	unsigned int irqs[3];
 	u32 node;
 	u64 flags;
-	u64 dar;
-	u64 dsisr;
 	u64 class_0_pending;
+	u64 class_0_dar;
+	u64 class_0_dsisr;
+	u64 class_1_dar;
+	u64 class_1_dsisr;
 	size_t ls_size;
 	unsigned int slb_replace;
 	struct mm_struct *mm;
@@ -143,7 +146,7 @@
 
 	void (* wbox_callback)(struct spu *spu);
 	void (* ibox_callback)(struct spu *spu);
-	void (* stop_callback)(struct spu *spu);
+	void (* stop_callback)(struct spu *spu, int irq);
 	void (* mfc_callback)(struct spu *spu);
 
 	char irq_c0[8];
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h
index 0ab6bff..129ec14 100644
--- a/include/asm-powerpc/spu_csa.h
+++ b/include/asm-powerpc/spu_csa.h
@@ -254,7 +254,8 @@
 	u64 spu_chnldata_RW[32];
 	u32 spu_mailbox_data[4];
 	u32 pu_mailbox_data[1];
-	u64 dar, dsisr, class_0_pending;
+	u64 class_0_dar, class_0_dsisr, class_0_pending;
+	u64 class_1_dar, class_1_dsisr;
 	unsigned long suspend_time;
 	spinlock_t register_lock;
 };
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index 0593cb8..70ebd33 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -178,7 +178,7 @@
 
 }
 
-extern inline void * xchg_ptr(void * m, void * val)
+static inline void * xchg_ptr(void * m, void * val)
 {
 	return (void *) xchg_u32(m, (unsigned long) val);
 }
diff --git a/include/asm-s390/kvm_host.h b/include/asm-s390/kvm_host.h
index f8204a4..18cbd8a 100644
--- a/include/asm-s390/kvm_host.h
+++ b/include/asm-s390/kvm_host.h
@@ -104,6 +104,7 @@
 
 struct kvm_vcpu_stat {
 	u32 exit_userspace;
+	u32 exit_null;
 	u32 exit_external_request;
 	u32 exit_external_interrupt;
 	u32 exit_stop_request;
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h
index f0f4579..12fd9c4 100644
--- a/include/asm-s390/page.h
+++ b/include/asm-s390/page.h
@@ -125,6 +125,17 @@
 	return skey;
 }
 
+#ifdef CONFIG_PAGE_STATES
+
+struct page;
+void arch_free_page(struct page *page, int order);
+void arch_alloc_page(struct page *page, int order);
+
+#define HAVE_ARCH_FREE_PAGE
+#define HAVE_ARCH_ALLOC_PAGE
+
+#endif
+
 #endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
index 441d7c2..d7d4e2e 100644
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -471,6 +471,8 @@
 extern void user_enable_single_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
+#define __ARCH_WANT_COMPAT_SYS_PTRACE
+
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
 #define regs_return_value(regs)((regs)->gprs[2])
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index c819ae2..e0d4500 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -116,6 +116,12 @@
 #define pfault_fini()		do { } while (0)
 #endif /* CONFIG_PFAULT */
 
+#ifdef CONFIG_PAGE_STATES
+extern void cmma_init(void);
+#else
+static inline void cmma_init(void) { }
+#endif
+
 #define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
 	account_vtime(prev);						     \
diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h
index 78dda03..0e959e2 100644
--- a/include/asm-s390/types.h
+++ b/include/asm-s390/types.h
@@ -10,9 +10,9 @@
 #define _S390_TYPES_H
 
 #ifndef __s390x__
-# include <asm-generic/int-l64.h>
-#else
 # include <asm-generic/int-ll64.h>
+#else
+# include <asm-generic/int-l64.h>
 #endif
 
 #ifndef __ASSEMBLY__
diff --git a/include/asm-sh/cpu-sh3/dma.h b/include/asm-sh/cpu-sh3/dma.h
index 092ff9d..6813c32 100644
--- a/include/asm-sh/cpu-sh3/dma.h
+++ b/include/asm-sh/cpu-sh3/dma.h
@@ -3,19 +3,19 @@
 
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
+    defined(CONFIG_CPU_SUBTYPE_SH7721)
 #define SH_DMAC_BASE	0xa4010020
+#else
+#define SH_DMAC_BASE	0xa4000020
+#endif
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709)
 #define DMTE0_IRQ	48
 #define DMTE1_IRQ	49
 #define DMTE2_IRQ	50
 #define DMTE3_IRQ	51
 #define DMTE4_IRQ	76
 #define DMTE5_IRQ	77
-
-#else
-#define SH_DMAC_BASE	0xa4000020
 #endif
 
 /* Definitions for the SuperH DMAC */
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h
index c958fda..7438d1e 100644
--- a/include/asm-sh/hw_irq.h
+++ b/include/asm-sh/hw_irq.h
@@ -79,6 +79,10 @@
 	struct intc_sense_reg *sense_regs;
 	unsigned int nr_sense_regs;
 	char *name;
+#ifdef CONFIG_CPU_SH3
+	struct intc_mask_reg *ack_regs;
+	unsigned int nr_ack_regs;
+#endif
 };
 
 #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
@@ -91,10 +95,25 @@
 	chipname,							\
 }
 
+#ifdef CONFIG_CPU_SH3
+#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups,	\
+	mask_regs, prio_regs, sense_regs, ack_regs)			\
+struct intc_desc symbol __initdata = {					\
+	_INTC_ARRAY(vectors), _INTC_ARRAY(groups),			\
+	_INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs),			\
+	_INTC_ARRAY(sense_regs),					\
+	chipname,							\
+	_INTC_ARRAY(ack_regs),						\
+}
+#endif
+
 void __init register_intc_controller(struct intc_desc *desc);
 int intc_set_priority(unsigned int irq, unsigned int prio);
 
 void __init plat_irq_setup(void);
+#ifdef CONFIG_CPU_SH3
+void __init plat_irq_setup_sh3(void);
+#endif
 
 enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210,
        IRQ_MODE_IRL7654_MASK, IRQ_MODE_IRL3210_MASK,
diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h
index 356e50d..a4fbf0c 100644
--- a/include/asm-sh/io.h
+++ b/include/asm-sh/io.h
@@ -268,11 +268,6 @@
 unsigned long long poke_real_address_q(unsigned long long addr,
 				       unsigned long long val);
 
-/* arch/sh/mm/ioremap_64.c */
-unsigned long onchip_remap(unsigned long addr, unsigned long size,
-			   const char *name);
-extern void onchip_unmap(unsigned long vaddr);
-
 #if !defined(CONFIG_MMU)
 #define virt_to_phys(address)	((unsigned long)(address))
 #define phys_to_virt(address)	((void *)(address))
@@ -302,9 +297,16 @@
 void __iomem *__ioremap(unsigned long offset, unsigned long size,
 			unsigned long flags);
 void __iounmap(void __iomem *addr);
+
+/* arch/sh/mm/ioremap_64.c */
+unsigned long onchip_remap(unsigned long addr, unsigned long size,
+			   const char *name);
+extern void onchip_unmap(unsigned long vaddr);
 #else
 #define __ioremap(offset, size, flags)	((void __iomem *)(offset))
 #define __iounmap(addr)			do { } while (0)
+#define onchip_remap(addr, size, name)	(addr)
+#define onchip_unmap(addr)		do { } while (0)
 #endif /* CONFIG_MMU */
 
 static inline void __iomem *
diff --git a/include/asm-sh/keyboard.h b/include/asm-sh/keyboard.h
deleted file mode 100644
index 31dcc4f..0000000
--- a/include/asm-sh/keyboard.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef	__ASM_SH_KEYBOARD_H
-#define	__ASM_SH_KEYBOARD_H
-/*
- *	$Id: keyboard.h,v 1.1.1.1 2001/10/15 20:45:09 mrbrown Exp $
- */
-
-#include <linux/kd.h>
-#include <asm/machvec.h>
-
-#ifdef CONFIG_SH_MPC1211
-#include <asm/mpc1211/keyboard-mpc1211.h>
-#endif
-#endif
diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h
index fe58d00..87e812f 100644
--- a/include/asm-sh/mmu_context.h
+++ b/include/asm-sh/mmu_context.h
@@ -27,6 +27,7 @@
 /* ASID is 8-bit value, so it can't be 0x100 */
 #define MMU_NO_ASID			0x100
 
+#ifdef CONFIG_MMU
 #define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
 #define cpu_context(cpu, mm)	((mm)->context.id[cpu])
 
@@ -38,7 +39,6 @@
  */
 #define MMU_VPN_MASK	0xfffff000
 
-#ifdef CONFIG_MMU
 #if defined(CONFIG_SUPERH32)
 #include "mmu_context_32.h"
 #else
@@ -129,6 +129,8 @@
 #define destroy_context(mm)		do { } while (0)
 #define set_asid(asid)			do { } while (0)
 #define get_asid()			(0)
+#define cpu_asid(cpu, mm)		({ (void)cpu; 0; })
+#define switch_and_save_asid(asid)	(0)
 #define set_TTB(pgd)			do { } while (0)
 #define get_TTB()			(0)
 #define activate_context(mm,cpu)	do { } while (0)
diff --git a/include/asm-sh/mmzone.h b/include/asm-sh/mmzone.h
index 7969f38..2969253 100644
--- a/include/asm-sh/mmzone.h
+++ b/include/asm-sh/mmzone.h
@@ -41,6 +41,8 @@
 
 /* arch/sh/kernel/setup.c */
 void __init setup_bootmem_allocator(unsigned long start_pfn);
+void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
+			       unsigned long end_pfn);
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_MMZONE_H */
diff --git a/include/asm-sh/mpc1211/dma.h b/include/asm-sh/mpc1211/dma.h
deleted file mode 100644
index e506d1a..0000000
--- a/include/asm-sh/mpc1211/dma.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
- * Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen
- * and John Boyd, Nov. 1992.
- */
-
-#ifndef _ASM_MPC1211_DMA_H
-#define _ASM_MPC1211_DMA_H
-
-#include <linux/spinlock.h>	/* And spinlocks */
-#include <asm/io.h>		/* need byte IO */
-#include <linux/delay.h>
-
-
-#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
-#define dma_outb	outb_p
-#else
-#define dma_outb	outb
-#endif
-
-#define dma_inb		inb
-
-/*
- * NOTES about DMA transfers:
- *
- *  controller 1: channels 0-3, byte operations, ports 00-1F
- *  controller 2: channels 4-7, word operations, ports C0-DF
- *
- *  - ALL registers are 8 bits only, regardless of transfer size
- *  - channel 4 is not used - cascades 1 into 2.
- *  - channels 0-3 are byte - addresses/counts are for physical bytes
- *  - channels 5-7 are word - addresses/counts are for physical words
- *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
- *  - transfer count loaded to registers is 1 less than actual count
- *  - controller 2 offsets are all even (2x offsets for controller 1)
- *  - page registers for 5-7 don't use data bit 0, represent 128K pages
- *  - page registers for 0-3 use bit 0, represent 64K pages
- *
- * DMA transfers are limited to the lower 16MB of _physical_ memory.  
- * Note that addresses loaded into registers must be _physical_ addresses,
- * not logical addresses (which may differ if paging is active).
- *
- *  Address mapping for channels 0-3:
- *
- *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
- *    |  ...  |   |  ... |   |  ... |
- *    |  ...  |   |  ... |   |  ... |
- *    |  ...  |   |  ... |   |  ... |
- *   P7  ...  P0  A7 ... A0  A7 ... A0   
- * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
- *
- *  Address mapping for channels 5-7:
- *
- *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
- *    |  ...  |   \   \   ... \  \  \  ... \  \
- *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
- *    |  ...  |     \   \   ... \  \  \  ... \
- *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
- * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
- *
- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
- * the hardware level, so odd-byte transfers aren't possible).
- *
- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
- * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
- * and up to 128K bytes may be transferred on channels 5-7 in one operation. 
- *
- */
-
-#define MAX_DMA_CHANNELS	8
-
-/* The maximum address that we can perform a DMA transfer to on this platform */
-#define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x10000000)
-
-/* 8237 DMA controllers */
-#define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
-#define IO_DMA2_BASE	0xC0	/* 16 bit master DMA, ch 4(=slave input)..7 */
-
-/* DMA controller registers */
-#define DMA1_CMD_REG		0x08	/* command register (w) */
-#define DMA1_STAT_REG		0x08	/* status register (r) */
-#define DMA1_REQ_REG            0x09    /* request register (w) */
-#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
-#define DMA1_MODE_REG		0x0B	/* mode register (w) */
-#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
-#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
-#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
-#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
-#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
-
-#define DMA2_CMD_REG		0xD0	/* command register (w) */
-#define DMA2_STAT_REG		0xD0	/* status register (r) */
-#define DMA2_REQ_REG            0xD2    /* request register (w) */
-#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
-#define DMA2_MODE_REG		0xD6	/* mode register (w) */
-#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
-#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
-#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
-#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
-#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
-
-#define DMA_ADDR_0              0x00    /* DMA address registers */
-#define DMA_ADDR_1              0x02
-#define DMA_ADDR_2              0x04
-#define DMA_ADDR_3              0x06
-#define DMA_ADDR_4              0xC0
-#define DMA_ADDR_5              0xC4
-#define DMA_ADDR_6              0xC8
-#define DMA_ADDR_7              0xCC
-
-#define DMA_CNT_0               0x01    /* DMA count registers */
-#define DMA_CNT_1               0x03
-#define DMA_CNT_2               0x05
-#define DMA_CNT_3               0x07
-#define DMA_CNT_4               0xC2
-#define DMA_CNT_5               0xC6
-#define DMA_CNT_6               0xCA
-#define DMA_CNT_7               0xCE
-
-#define DMA_PAGE_0              0x87    /* DMA page registers */
-#define DMA_PAGE_1              0x83
-#define DMA_PAGE_2              0x81
-#define DMA_PAGE_3              0x82
-#define DMA_PAGE_5              0x8B
-#define DMA_PAGE_6              0x89
-#define DMA_PAGE_7              0x8A
-
-#define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
-#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
-
-#define DMA_AUTOINIT	0x10
-
-
-extern spinlock_t  dma_spin_lock;
-
-static __inline__ unsigned long claim_dma_lock(void)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&dma_spin_lock, flags);
-	return flags;
-}
-
-static __inline__ void release_dma_lock(unsigned long flags)
-{
-	spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
-	if (dmanr<=3)
-		dma_outb(dmanr,  DMA1_MASK_REG);
-	else
-		dma_outb(dmanr & 3,  DMA2_MASK_REG);
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
-	if (dmanr<=3)
-		dma_outb(dmanr | 4,  DMA1_MASK_REG);
-	else
-		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
-}
-
-/* Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while holding the DMA lock ! ---
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-	if (dmanr<=3)
-		dma_outb(0,  DMA1_CLEAR_FF_REG);
-	else
-		dma_outb(0,  DMA2_CLEAR_FF_REG);
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-	if (dmanr<=3)
-		dma_outb(mode | dmanr,  DMA1_MODE_REG);
-	else
-		dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
-}
-
-/* Set only the page register bits of the transfer address.
- * This is used for successive transfers when we know the contents of
- * the lower 16 bits of the DMA current address register, but a 64k boundary
- * may have been crossed.
- */
-static __inline__ void set_dma_page(unsigned int dmanr, unsigned int pagenr)
-{
-	switch(dmanr) {
-		case 0:
-			dma_outb( pagenr       & 0xff, DMA_PAGE_0);
-			dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_0 + 0x400);
-			break;
-		case 1:
-			dma_outb( pagenr       & 0xff, DMA_PAGE_1);
-			dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_1 + 0x400);
-			break;
-		case 2:
-			dma_outb( pagenr       & 0xff, DMA_PAGE_2);
-			dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_2 + 0x400);
-			break;
-		case 3:
-			dma_outb( pagenr       & 0xff, DMA_PAGE_3);
-			dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_3 + 0x400);
-			break;
-		case 5:
-			dma_outb( pagenr       & 0xfe, DMA_PAGE_5);
-			dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_5 + 0x400);
-			break;
-		case 6:
-			dma_outb( pagenr       & 0xfe, DMA_PAGE_6);
-			dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_6 + 0x400);
-			break;
-		case 7:
-			dma_outb( pagenr       & 0xfe, DMA_PAGE_7);
-			dma_outb((pagenr >> 8) & 0xff, DMA_PAGE_7 + 0x400);
-			break;
-       	}
-}
-
-
-/* Set transfer address & page bits for specific DMA channel.
- * Assumes dma flipflop is clear.
- */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
-	set_dma_page(dmanr, a>>16);
-	if (dmanr <= 3)  {
-	    dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
-            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
-	}  else  {
-	    dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
-	    dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
-	}
-}
-
-
-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
- * a specific DMA channel.
- * You must ensure the parameters are valid.
- * NOTE: from a manual: "the number of transfers is one more
- * than the initial word count"! This is taken into account.
- * Assumes dma flip-flop is clear.
- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-        count--;
-	if (dmanr <= 3)  {
-	    dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
-	    dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
-        } else {
-	    dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
-	    dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
-        }
-}
-
-
-/* Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * If called before the channel has been used, it may return 1.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- *
- * Assumes DMA flip-flop is clear.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
-	unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
-					 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
-
-	/* using short to get 16-bit wrap around */
-	unsigned short count;
-
-	count = 1 + dma_inb(io_port);
-	count += dma_inb(io_port) << 8;
-	return (dmanr<=3)? count : (count<<1);
-}
-
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);	/* release it again */
-
-/* From PCI */
-
-#ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
-#else
-#define isa_dma_bridge_buggy 	(0)
-#endif
-
-#endif /* _ASM_MPC1211_DMA_H */
diff --git a/include/asm-sh/mpc1211/io.h b/include/asm-sh/mpc1211/io.h
deleted file mode 100644
index 6298370..0000000
--- a/include/asm-sh/mpc1211/io.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * include/asm-sh/mpc1211/io.h
- *
- * Copyright 2001 Saito.K & Jeanne
- *
- * IO functions for an Interface MPC-1211
- */
-
-#ifndef _ASM_SH_IO_MPC1211_H
-#define _ASM_SH_IO_MPC1211_H
-
-#include <linux/time.h>
-
-extern int mpc1211_irq_demux(int irq);
-
-extern void init_mpc1211_IRQ(void);
-extern void heartbeat_mpc1211(void);
-
-extern void mpc1211_rtc_gettimeofday(struct timeval *tv);
-extern int mpc1211_rtc_settimeofday(const struct timeval *tv);
-
-#endif /* _ASM_SH_IO_MPC1211_H */
diff --git a/include/asm-sh/mpc1211/keyboard.h b/include/asm-sh/mpc1211/keyboard.h
deleted file mode 100644
index 9020fee..0000000
--- a/include/asm-sh/mpc1211/keyboard.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  MPC1211 specific keybord definitions
- *  Taken from the old asm-i386/keybord.h for PC/AT-style definitions
- *  created 3 Nov 1996 by Geert Uytterhoeven.
- */
-
-#ifdef __KERNEL__
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/kd.h>
-#include <linux/pm.h>
-#include <asm/io.h>
-
-#define KEYBOARD_IRQ			1
-#define DISABLE_KBD_DURING_INTERRUPTS	0
-
-extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
-			   char raw_mode);
-extern char pckbd_unexpected_up(unsigned char keycode);
-extern void pckbd_leds(unsigned char leds);
-extern void pckbd_init_hw(void);
-extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *);
-extern pm_callback pm_kbd_request_override;
-
-#define kbd_setkeycode		pckbd_setkeycode
-#define kbd_getkeycode		pckbd_getkeycode
-#define kbd_translate		pckbd_translate
-#define kbd_unexpected_up	pckbd_unexpected_up
-#define kbd_leds		pckbd_leds
-#define kbd_init_hw		pckbd_init_hw
-
-/* resource allocation */
-#define kbd_request_region()
-#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
-                                             "keyboard", NULL)
-
-/* How to access the keyboard macros on this platform.  */
-#define kbd_read_input() inb(KBD_DATA_REG)
-#define kbd_read_status() inb(KBD_STATUS_REG)
-#define kbd_write_output(val) outb(val, KBD_DATA_REG)
-#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
-
-/* Some stoneage hardware needs delays after some operations.  */
-#define kbd_pause() do { } while(0)
-
-/*
- * Machine specific bits for the PS/2 driver
- */
-
-#define AUX_IRQ 12
-
-#define aux_request_irq(hand, dev_id)					\
-	request_irq(AUX_IRQ, hand, IRQF_SHARED, "PS2 Mouse", dev_id)
-
-#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
-
-#endif /* __KERNEL__ */
diff --git a/include/asm-sh/mpc1211/m1543c.h b/include/asm-sh/mpc1211/m1543c.h
deleted file mode 100644
index c95d132..0000000
--- a/include/asm-sh/mpc1211/m1543c.h
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef __ASM_SH_M1543C_H
-#define __ASM_SH_M1543C_H
-
-/*
- * linux/include/asm-sh/m1543c.h
- * Copyright (C) 2001  Nobuhiro Sakawa
- * M1543C:PCI-ISA Bus Bridge with Super IO Chip support
- *
- * from
- *
- * linux/include/asm-sh/smc37c93x.h
- *
- * Copyright (C) 2000  Kazumoto Kojima
- *
- * SMSC 37C93x Super IO Chip support
- */
-
-/* Default base I/O address */
-#define FDC_PRIMARY_BASE	0x3f0
-#define IDE1_PRIMARY_BASE	0x1f0
-#define IDE1_SECONDARY_BASE	0x170
-#define PARPORT_PRIMARY_BASE	0x378
-#define COM1_PRIMARY_BASE	0x2f8
-#define COM2_PRIMARY_BASE	0x3f8
-#define COM3_PRIMARY_BASE	0x3e8
-#define RTC_PRIMARY_BASE	0x070
-#define KBC_PRIMARY_BASE	0x060
-#define AUXIO_PRIMARY_BASE	0x000	/* XXX */
-#define I8259_M_CR		0x20
-#define I8259_M_MR		0x21
-#define I8259_S_CR		0xa0
-#define I8259_S_MR		0xa1
-
-/* Logical device number */
-#define LDN_FDC			0
-#define LDN_IDE1		1
-#define LDN_IDE2		2
-#define LDN_PARPORT		3
-#define LDN_COM1		4
-#define LDN_COM2		5
-#define LDN_COM3		11
-#define LDN_RTC			6
-#define LDN_KBC			7
-
-/* Configuration port and key */
-#define CONFIG_PORT		0x3f0
-#define INDEX_PORT		CONFIG_PORT
-#define DATA_PORT		0x3f1
-#define CONFIG_ENTER1		0x51
-#define CONFIG_ENTER2		0x23
-#define CONFIG_EXIT		0xbb
-
-/* Configuration index */
-#define CURRENT_LDN_INDEX	0x07
-#define POWER_CONTROL_INDEX	0x22
-#define ACTIVATE_INDEX		0x30
-#define IO_BASE_HI_INDEX	0x60
-#define IO_BASE_LO_INDEX	0x61
-#define IRQ_SELECT_INDEX	0x70
-#define PS2_IRQ_INDEX		0x72
-#define DMA_SELECT_INDEX	0x74
-
-/* UART stuff. Only for debugging.  */
-/* UART Register */
-
-#define UART_RBR	0x0	/* Receiver Buffer Register (Read Only) */
-#define UART_THR	0x0	/* Transmitter Holding Register (Write Only) */
-#define UART_IER	0x2	/* Interrupt Enable Register */
-#define UART_IIR	0x4	/* Interrupt Ident Register (Read Only) */
-#define UART_FCR	0x4	/* FIFO Control Register (Write Only) */
-#define UART_LCR	0x6	/* Line Control Register */
-#define UART_MCR	0x8	/* MODEM Control Register */
-#define UART_LSR	0xa	/* Line Status Register */
-#define UART_MSR	0xc	/* MODEM Status Register */
-#define UART_SCR	0xe	/* Scratch Register */
-#define UART_DLL	0x0	/* Divisor Latch (LS) */
-#define UART_DLM	0x2	/* Divisor Latch (MS) */
-
-#ifndef __ASSEMBLY__
-typedef struct uart_reg {
-	volatile __u16 rbr;
-	volatile __u16 ier;
-	volatile __u16 iir;
-	volatile __u16 lcr;
-	volatile __u16 mcr;
-	volatile __u16 lsr;
-	volatile __u16 msr;
-	volatile __u16 scr;
-} uart_reg;
-#endif /* ! __ASSEMBLY__ */
-
-/* Alias for Write Only Register */
-
-#define thr	rbr
-#define tcr	iir
-
-/* Alias for Divisor Latch Register */
-
-#define dll	rbr
-#define dlm	ier
-#define fcr	iir
-
-/* Interrupt Enable Register */
-
-#define IER_ERDAI	0x0100	/* Enable Received Data Available Interrupt */
-#define IER_ETHREI	0x0200	/* Enable Transmitter Holding Register Empty Interrupt */
-#define IER_ELSI	0x0400	/* Enable Receiver Line Status Interrupt */
-#define IER_EMSI	0x0800	/* Enable MODEM Status Interrupt */
-
-/* Interrupt Ident Register */
-
-#define IIR_IP		0x0100	/* "0" if Interrupt Pending */
-#define IIR_IIB0	0x0200	/* Interrupt ID Bit 0 */
-#define IIR_IIB1	0x0400	/* Interrupt ID Bit 1 */
-#define IIR_IIB2	0x0800	/* Interrupt ID Bit 2 */
-#define IIR_FIFO	0xc000	/* FIFOs enabled */
-
-/* FIFO Control Register */
-
-#define FCR_FEN		0x0100	/* FIFO enable */
-#define FCR_RFRES	0x0200	/* Receiver FIFO reset */
-#define FCR_TFRES	0x0400	/* Transmitter FIFO reset */
-#define FCR_DMA		0x0800	/* DMA mode select */
-#define FCR_RTL		0x4000	/* Receiver triger (LSB) */
-#define FCR_RTM		0x8000	/* Receiver triger (MSB) */
-
-/* Line Control Register */
-
-#define LCR_WLS0	0x0100	/* Word Length Select Bit 0 */
-#define LCR_WLS1	0x0200	/* Word Length Select Bit 1 */
-#define LCR_STB		0x0400	/* Number of Stop Bits */
-#define LCR_PEN		0x0800	/* Parity Enable */
-#define LCR_EPS		0x1000	/* Even Parity Select */
-#define LCR_SP		0x2000	/* Stick Parity */
-#define LCR_SB		0x4000	/* Set Break */
-#define LCR_DLAB	0x8000	/* Divisor Latch Access Bit */
-
-/* MODEM Control Register */
-
-#define MCR_DTR		0x0100	/* Data Terminal Ready */
-#define MCR_RTS		0x0200	/* Request to Send */
-#define MCR_OUT1	0x0400	/* Out 1 */
-#define MCR_IRQEN	0x0800	/* IRQ Enable */
-#define MCR_LOOP	0x1000	/* Loop */
-
-/* Line Status Register */
-
-#define LSR_DR		0x0100	/* Data Ready */
-#define LSR_OE		0x0200	/* Overrun Error */
-#define LSR_PE		0x0400	/* Parity Error */
-#define LSR_FE		0x0800	/* Framing Error */
-#define LSR_BI		0x1000	/* Break Interrupt */
-#define LSR_THRE	0x2000	/* Transmitter Holding Register Empty */
-#define LSR_TEMT	0x4000	/* Transmitter Empty */
-#define LSR_FIFOE	0x8000	/* Receiver FIFO error */
-
-/* MODEM Status Register */
-
-#define MSR_DCTS	0x0100	/* Delta Clear to Send */
-#define MSR_DDSR	0x0200	/* Delta Data Set Ready */
-#define MSR_TERI	0x0400	/* Trailing Edge Ring Indicator */
-#define MSR_DDCD	0x0800	/* Delta Data Carrier Detect */
-#define MSR_CTS		0x1000	/* Clear to Send */
-#define MSR_DSR		0x2000	/* Data Set Ready */
-#define MSR_RI		0x4000	/* Ring Indicator */
-#define MSR_DCD		0x8000	/* Data Carrier Detect */
-
-/* Baud Rate Divisor */
-
-#define UART_CLK	(1843200)	/* 1.8432 MHz */
-#define UART_BAUD(x)	(UART_CLK / (16 * (x)))
-
-/* RTC register definition */
-#define RTC_SECONDS             0
-#define RTC_SECONDS_ALARM       1
-#define RTC_MINUTES             2
-#define RTC_MINUTES_ALARM       3
-#define RTC_HOURS               4
-#define RTC_HOURS_ALARM         5
-#define RTC_DAY_OF_WEEK         6
-#define RTC_DAY_OF_MONTH        7
-#define RTC_MONTH               8
-#define RTC_YEAR                9
-#define RTC_FREQ_SELECT		10
-# define RTC_UIP 0x80
-# define RTC_DIV_CTL 0x70
-/* This RTC can work under 32.768KHz clock only.  */
-# define RTC_OSC_ENABLE 0x20
-# define RTC_OSC_DISABLE 0x00
-#define RTC_CONTROL     	11
-# define RTC_SET 0x80
-# define RTC_PIE 0x40
-# define RTC_AIE 0x20
-# define RTC_UIE 0x10
-# define RTC_SQWE 0x08
-# define RTC_DM_BINARY 0x04
-# define RTC_24H 0x02
-# define RTC_DST_EN 0x01
-
-#endif  /* __ASM_SH_M1543C_H */
diff --git a/include/asm-sh/mpc1211/mc146818rtc.h b/include/asm-sh/mpc1211/mc146818rtc.h
deleted file mode 100644
index e245f2a..0000000
--- a/include/asm-sh/mpc1211/mc146818rtc.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * MPC1211 uses PC/AT style RTC definitions.
- */
-#include <asm-x86/mc146818rtc_32.h>
-
-
diff --git a/include/asm-sh/mpc1211/mpc1211.h b/include/asm-sh/mpc1211/mpc1211.h
deleted file mode 100644
index fa456c3..0000000
--- a/include/asm-sh/mpc1211/mpc1211.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __ASM_SH_MPC1211_H
-#define __ASM_SH_MPC1211_H
-
-/*
- * linux/include/asm-sh/mpc1211.h
- *
- * Copyright (C) 2001  Saito.K & Jeanne
- *
- * Interface MPC-1211 support
- */
-
-#define PA_PCI_IO       (0xa4000000)    /* PCI I/O space */
-#define PA_PCI_MEM      (0xb0000000)    /* PCI MEM space */
-
-#define PCIPAR          (0xa4000cf8)    /* PCI Config address */
-#define PCIPDR          (0xa4000cfc)    /* PCI Config data    */
-
-#endif  /* __ASM_SH_MPC1211_H */
diff --git a/include/asm-sh/mpc1211/pci.h b/include/asm-sh/mpc1211/pci.h
deleted file mode 100644
index d9162c5..0000000
--- a/include/asm-sh/mpc1211/pci.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *	Low-Level PCI Support for MPC-1211
- *
- *      (c) 2002 Saito.K & Jeanne
- *
- */
-
-#ifndef _PCI_MPC1211_H_
-#define _PCI_MPC1211_H_
-
-#include <linux/pci.h>
-
-/* set debug level 4=verbose...1=terse */
-//#define DEBUG_PCI 3
-#undef DEBUG_PCI
-
-#ifdef DEBUG_PCI
-#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
-#else
-#define PCIDBG(n, x...)
-#endif
-
-/* startup values */
-#define PCI_PROBE_BIOS    1
-#define PCI_PROBE_CONF1   2
-#define PCI_PROBE_CONF2   4
-#define PCI_NO_CHECKS     0x400
-#define PCI_ASSIGN_ROMS   0x1000
-#define PCI_BIOS_IRQ_SCAN 0x2000
-
-/* MPC-1211 Specific Values */
-#define PCIPAR            (0xa4000cf8)    /* PCI Config address */
-#define PCIPDR            (0xa4000cfc)    /* PCI Config data    */
-
-#define PA_PCI_IO         (0xa4000000)    /* PCI I/O space */
-#define PA_PCI_MEM        (0xb0000000)    /* PCI MEM space */
-
-#endif /* _PCI_MPC1211_H_ */
diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h
index a33838f..306f735 100644
--- a/include/asm-sh/r7780rp.h
+++ b/include/asm-sh/r7780rp.h
@@ -193,8 +193,6 @@
 #define IRQ_SCIF0		(HL_FPGA_IRQ_BASE + 15)
 #define IRQ_SCIF1		(HL_FPGA_IRQ_BASE + 16)
 
-unsigned char *highlander_init_irq_r7780mp(void);
-unsigned char *highlander_init_irq_r7780rp(void);
-unsigned char *highlander_init_irq_r7785rp(void);
+unsigned char *highlander_plat_irq_setup(void);
 
 #endif  /* __ASM_SH_RENESAS_R7780RP */
diff --git a/include/asm-sh/tlb_64.h b/include/asm-sh/tlb_64.h
index 0308e05..0a96f3a 100644
--- a/include/asm-sh/tlb_64.h
+++ b/include/asm-sh/tlb_64.h
@@ -56,6 +56,7 @@
 	__asm__ __volatile__ ("putcfg %0, 0, r63\n" : : "r" (slot));
 }
 
+#ifdef CONFIG_MMU
 /* arch/sh64/mm/tlb.c */
 int sh64_tlb_init(void);
 unsigned long long sh64_next_free_dtlb_entry(void);
@@ -64,6 +65,13 @@
 void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr,
 			 unsigned long asid, unsigned long paddr);
 void sh64_teardown_tlb_slot(unsigned long long config_addr);
-
+#else
+#define sh64_tlb_init()					do { } while (0)
+#define sh64_next_free_dtlb_entry()			(0)
+#define sh64_get_wired_dtlb_entry()			(0)
+#define sh64_put_wired_dtlb_entry(entry)		do { } while (0)
+#define sh64_setup_tlb_slot(conf, virt, asid, phys)	do { } while (0)
+#define sh64_teardown_tlb_slot(addr)			do { } while (0)
+#endif /* CONFIG_MMU */
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_SH_TLB_64_H */
diff --git a/include/asm-sh/topology.h b/include/asm-sh/topology.h
index 34cdb28..95f0085 100644
--- a/include/asm-sh/topology.h
+++ b/include/asm-sh/topology.h
@@ -29,6 +29,17 @@
 	.nr_balance_failed	= 0,			\
 }
 
+#define cpu_to_node(cpu)	((void)(cpu),0)
+#define parent_node(node)	((void)(node),0)
+
+#define node_to_cpumask(node)	((void)node, cpu_online_map)
+#define node_to_first_cpu(node)	((void)(node),0)
+
+#define pcibus_to_node(bus)	((void)(bus), -1)
+#define pcibus_to_cpumask(bus)	(pcibus_to_node(bus) == -1 ? \
+					CPU_MASK_ALL : \
+					node_to_cpumask(pcibus_to_node(bus)) \
+				)
 #endif
 
 #include <asm-generic/topology.h>
diff --git a/include/asm-sh/uaccess_64.h b/include/asm-sh/uaccess_64.h
index f956b7b..a9b68d0 100644
--- a/include/asm-sh/uaccess_64.h
+++ b/include/asm-sh/uaccess_64.h
@@ -274,7 +274,9 @@
 	unsigned long insn, fixup;
 };
 
+#ifdef CONFIG_MMU
 #define ARCH_HAS_SEARCH_EXTABLE
+#endif
 
 /* Returns 0 if exception not found and fixup.unit otherwise.  */
 extern unsigned long search_exception_table(unsigned long addr);
diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
index e18be98..3d16b40 100644
--- a/include/asm-sparc/mman.h
+++ b/include/asm-sparc/mman.h
@@ -24,9 +24,8 @@
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
-#define arch_mmap_check	sparc_mmap_check
-int sparc_mmap_check(unsigned long addr, unsigned long len,
-		unsigned long flags);
+#define arch_mmap_check(addr,len,flags)	sparc_mmap_check(addr,len)
+int sparc_mmap_check(unsigned long addr, unsigned long len);
 #endif
 #endif
 
diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h
index 19c9780..2139704 100644
--- a/include/asm-sparc/psr.h
+++ b/include/asm-sparc/psr.h
@@ -25,6 +25,7 @@
 #define PSR_PIL     0x00000f00         /* processor interrupt level  */
 #define PSR_EF      0x00001000         /* enable floating point      */
 #define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
 #define PSR_LE      0x00008000         /* SuperSparcII little-endian */
 #define PSR_ICC     0x00f00000         /* integer condition codes    */
 #define PSR_C       0x00100000         /* carry bit                  */
diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
index 8201a7b..0afb867 100644
--- a/include/asm-sparc/ptrace.h
+++ b/include/asm-sparc/ptrace.h
@@ -10,6 +10,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/types.h>
+
 struct pt_regs {
 	unsigned long psr;
 	unsigned long pc;
@@ -39,6 +41,16 @@
 #define UREG_FP        UREG_I6
 #define UREG_RETPC     UREG_I7
 
+static inline bool pt_regs_is_syscall(struct pt_regs *regs)
+{
+	return (regs->psr & PSR_SYSCALL);
+}
+
+static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
+{
+	return (regs->psr &= ~PSR_SYSCALL);
+}
+
 /* A register window */
 struct reg_window {
 	unsigned long locals[8];
@@ -149,6 +161,7 @@
 #define SF_XXARG  0x5c
 
 /* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH       11
 #define PTRACE_GETREGS            12
 #define PTRACE_SETREGS            13
 #define PTRACE_GETFPREGS          14
diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h
index d03a21c..94071c7 100644
--- a/include/asm-sparc/signal.h
+++ b/include/asm-sparc/signal.h
@@ -199,13 +199,7 @@
 	size_t		ss_size;
 } stack_t;
 
-struct sparc_deliver_cookie {
-	int restart_syscall;
-	unsigned long orig_i0;
-};
-
-struct pt_regs;
-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #endif /* !(__KERNEL__) */
 
diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
index e584563..625be4d 100644
--- a/include/asm-sparc64/mman.h
+++ b/include/asm-sparc64/mman.h
@@ -24,9 +24,8 @@
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
-#define arch_mmap_check	sparc64_mmap_check
-int sparc64_mmap_check(unsigned long addr, unsigned long len,
-		unsigned long flags);
+#define arch_mmap_check(addr,len,flags)	sparc64_mmap_check(addr,len)
+int sparc64_mmap_check(unsigned long addr, unsigned long len);
 #endif
 #endif
 
diff --git a/include/asm-sparc64/psrcompat.h b/include/asm-sparc64/psrcompat.h
index 5590ce6..3614ca0 100644
--- a/include/asm-sparc64/psrcompat.h
+++ b/include/asm-sparc64/psrcompat.h
@@ -12,6 +12,7 @@
 #define PSR_PIL     0x00000f00         /* processor interrupt level  */
 #define PSR_EF      0x00001000         /* enable floating point      */
 #define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
 #define PSR_LE      0x00008000         /* SuperSparcII little-endian */
 #define PSR_ICC     0x00f00000         /* integer condition codes    */
 #define PSR_C       0x00100000         /* carry bit                  */
@@ -30,6 +31,7 @@
 		PSR_S					|
 		((tstate & TSTATE_ICC) >> 12)		|
 		((tstate & TSTATE_XCC) >> 20)		|
+		((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) |
 		PSR_V8PLUS);
 }
 
diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h
index f3c4548..949aeba 100644
--- a/include/asm-sparc64/pstate.h
+++ b/include/asm-sparc64/pstate.h
@@ -62,6 +62,7 @@
 #define TSTATE_PRIV	_AC(0x0000000000000400,UL) /* Privilege.	*/
 #define TSTATE_IE	_AC(0x0000000000000200,UL) /* Interrupt Enable.	*/
 #define TSTATE_AG	_AC(0x0000000000000100,UL) /* Alternate Globals.*/
+#define TSTATE_SYSCALL	_AC(0x0000000000000020,UL) /* in syscall trap   */
 #define TSTATE_CWP	_AC(0x000000000000001f,UL) /* Curr Win-Pointer.	*/
 
 /* Floating-Point Registers State Register.
diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
index 714b819..90972a5 100644
--- a/include/asm-sparc64/ptrace.h
+++ b/include/asm-sparc64/ptrace.h
@@ -42,16 +42,14 @@
 	return regs->magic & 0x1ff;
 }
 
-static inline int pt_regs_clear_trap_type(struct pt_regs *regs)
-{
-	return regs->magic &= ~0x1ff;
-}
-
 static inline bool pt_regs_is_syscall(struct pt_regs *regs)
 {
-	int tt = pt_regs_trap_type(regs);
+	return (regs->tstate & TSTATE_SYSCALL);
+}
 
-	return (tt == 0x110 || tt == 0x111 || tt == 0x16d);
+static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
+{
+	return (regs->tstate &= ~TSTATE_SYSCALL);
 }
 
 struct pt_regs32 {
@@ -298,6 +296,7 @@
 #define SF_XXARG  0x5c
 
 /* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH       11
 #define PTRACE_GETREGS            12
 #define PTRACE_SETREGS            13
 #define PTRACE_GETFPREGS          14
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
index fa6f467..c49f32d 100644
--- a/include/asm-sparc64/signal.h
+++ b/include/asm-sparc64/signal.h
@@ -186,13 +186,7 @@
 	void __user		*ka_restorer;
 };
 
-struct signal_deliver_cookie {
-	int restart_syscall;
-	unsigned long orig_i0;
-};
-
-struct pt_regs;
-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #endif /* !(__KERNEL__) */
 
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index 71e42d1..e5873e3 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -38,7 +38,7 @@
 	struct task_struct	*task;
 	unsigned long		flags;
 	__u8			fpsaved[7];
-	__u8			pad;
+	__u8			status;
 	unsigned long		ksp;
 
 	/* D$ line 2 */
@@ -217,7 +217,7 @@
  *	 nop
  */
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
-#define TIF_RESTORE_SIGMASK	1	/* restore signal mask in do_signal() */
+/* flags bit 1 is available */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_PERFCTR		4	/* performance counters active */
@@ -244,14 +244,34 @@
 #define _TIF_32BIT		(1<<TIF_32BIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
-				 (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \
+				 (_TIF_SIGPENDING | \
 				  _TIF_NEED_RESCHED | _TIF_PERFCTR))
 
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ *
+ * Note that there are only 8 bits available.
+ */
+#define TS_RESTORE_SIGMASK	0x0001	/* restore signal mask in do_signal() */
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK	1
+static inline void set_restore_sigmask(void)
+{
+	struct thread_info *ti = current_thread_info();
+	ti->status |= TS_RESTORE_SIGMASK;
+	set_bit(TIF_SIGPENDING, &ti->flags);
+}
+#endif	/* !__ASSEMBLY__ */
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h
index 1b55538..52d67d3 100644
--- a/include/asm-sparc64/ttable.h
+++ b/include/asm-sparc64/ttable.h
@@ -91,13 +91,14 @@
 	 nop;
 	
 #define SYSCALL_TRAP(routine, systbl)			\
+	rdpr	%pil, %g2;				\
+	mov	TSTATE_SYSCALL, %g3;			\
 	sethi	%hi(109f), %g7;				\
-	ba,pt	%xcc, etrap;				\
+	ba,pt	%xcc, etrap_syscall;			\
 109:	 or	%g7, %lo(109b), %g7;			\
 	sethi	%hi(systbl), %l7;			\
 	ba,pt	%xcc, routine;				\
-	 or	%l7, %lo(systbl), %l7;			\
-	nop; nop;
+	 or	%l7, %lo(systbl), %l7;
 	
 #define TRAP_UTRAP(handler,lvl)				\
 	mov	handler, %g3;				\
diff --git a/include/asm-um/irq.h b/include/asm-um/irq.h
index de389a4..4a2037f 100644
--- a/include/asm-um/irq.h
+++ b/include/asm-um/irq.h
@@ -15,8 +15,9 @@
 #define SIGIO_WRITE_IRQ 	11
 #define TELNETD_IRQ 		12
 #define XTERM_IRQ 		13
+#define RANDOM_IRQ 		14
 
-#define LAST_IRQ XTERM_IRQ
+#define LAST_IRQ RANDOM_IRQ
 #define NR_IRQS (LAST_IRQ + 1)
 
 #endif
diff --git a/include/asm-um/keyboard.h b/include/asm-um/keyboard.h
deleted file mode 100644
index ee2e230..0000000
--- a/include/asm-um/keyboard.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_KEYBOARD_H
-#define __UM_KEYBOARD_H
-
-#include "asm/arch/keyboard.h"
-
-#endif
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 381f96b..916e1a6 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -7,16 +7,20 @@
 #ifndef __UM_PAGE_H
 #define __UM_PAGE_H
 
+#include <linux/const.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifndef __ASSEMBLY__
+
 struct page;
 
 #include <linux/types.h>
 #include <asm/vm-flags.h>
 
-/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT	12
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
-#define PAGE_MASK	(~(PAGE_SIZE-1))
-
 /*
  * These are used to make use of C type-checking..
  */
@@ -120,4 +124,5 @@
 #include <asm-generic/memory_model.h>
 #include <asm-generic/page.h>
 
-#endif
+#endif	/* __ASSEMBLY__ */
+#endif	/* __UM_PAGE_H */
diff --git a/include/asm-um/param.h b/include/asm-um/param.h
index 4cd4a22..e44f4e6 100644
--- a/include/asm-um/param.h
+++ b/include/asm-um/param.h
@@ -13,6 +13,8 @@
 #define HZ CONFIG_HZ
 #define USER_HZ	100	   /* .. some user interfaces are in "ticks" */
 #define CLOCKS_PER_SEC (USER_HZ)  /* frequency at which times() counts */
+#else
+#define HZ 100
 #endif
 
 #endif
diff --git a/include/asm-v850/param.h b/include/asm-v850/param.h
index 2818326..4391f5f 100644
--- a/include/asm-v850/param.h
+++ b/include/asm-v850/param.h
@@ -26,6 +26,8 @@
 # define HZ		CONFIG_HZ
 # define USER_HZ	100
 # define CLOCKS_PER_SEC	USER_HZ
+#else
+# define HZ		100
 #endif
 
 #endif /* __V850_PARAM_H__ */
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h
index b81a4d4..ee4b3ea 100644
--- a/include/asm-x86/bitops.h
+++ b/include/asm-x86/bitops.h
@@ -23,13 +23,10 @@
 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
 /* Technically wrong, but this avoids compilation errors on some gcc
    versions. */
-#define ADDR "=m" (*(volatile long *)addr)
-#define BIT_ADDR "=m" (((volatile int *)addr)[nr >> 5])
+#define ADDR "=m" (*(volatile long *) addr)
 #else
 #define ADDR "+m" (*(volatile long *) addr)
-#define BIT_ADDR "+m" (((volatile int *)addr)[nr >> 5])
 #endif
-#define BASE_ADDR "m" (*(volatile int *)addr)
 
 /**
  * set_bit - Atomically set a bit in memory
@@ -77,7 +74,7 @@
  */
 static inline void clear_bit(int nr, volatile void *addr)
 {
-	asm volatile(LOCK_PREFIX "btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+	asm volatile(LOCK_PREFIX "btr %1,%0" : ADDR : "Ir" (nr));
 }
 
 /*
@@ -96,7 +93,7 @@
 
 static inline void __clear_bit(int nr, volatile void *addr)
 {
-	asm volatile("btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+	asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
 }
 
 /*
@@ -131,7 +128,7 @@
  */
 static inline void __change_bit(int nr, volatile void *addr)
 {
-	asm volatile("btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+	asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
 }
 
 /**
@@ -145,7 +142,7 @@
  */
 static inline void change_bit(int nr, volatile void *addr)
 {
-	asm volatile(LOCK_PREFIX "btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR);
+	asm volatile(LOCK_PREFIX "btc %1,%0" : ADDR : "Ir" (nr));
 }
 
 /**
@@ -191,9 +188,10 @@
 {
 	int oldbit;
 
-	asm volatile("bts %2,%3\n\t"
-		     "sbb %0,%0"
-		     : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+	asm("bts %2,%1\n\t"
+	    "sbb %0,%0"
+	    : "=r" (oldbit), ADDR
+	    : "Ir" (nr));
 	return oldbit;
 }
 
@@ -229,9 +227,10 @@
 {
 	int oldbit;
 
-	asm volatile("btr %2,%3\n\t"
+	asm volatile("btr %2,%1\n\t"
 		     "sbb %0,%0"
-		     : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+		     : "=r" (oldbit), ADDR
+		     : "Ir" (nr));
 	return oldbit;
 }
 
@@ -240,9 +239,10 @@
 {
 	int oldbit;
 
-	asm volatile("btc %2,%3\n\t"
+	asm volatile("btc %2,%1\n\t"
 		     "sbb %0,%0"
-		     : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR);
+		     : "=r" (oldbit), ADDR
+		     : "Ir" (nr) : "memory");
 
 	return oldbit;
 }
@@ -276,11 +276,10 @@
 {
 	int oldbit;
 
-	asm volatile("bt %2,%3\n\t"
+	asm volatile("bt %2,%1\n\t"
 		     "sbb %0,%0"
 		     : "=r" (oldbit)
-		     : "m" (((volatile const int *)addr)[nr >> 5]),
-		       "Ir" (nr), BASE_ADDR);
+		     : "m" (*(unsigned long *)addr), "Ir" (nr));
 
 	return oldbit;
 }
@@ -397,8 +396,6 @@
 }
 #endif /* __KERNEL__ */
 
-#undef BASE_ADDR
-#undef BIT_ADDR
 #undef ADDR
 
 static inline void set_bit_string(unsigned long *bitmap,
diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h
index 7154dc4..6e64588 100644
--- a/include/asm-x86/geode.h
+++ b/include/asm-x86/geode.h
@@ -185,16 +185,14 @@
 	return (is_geode_gx() || is_geode_lx());
 }
 
-/*
- * The VSA has virtual registers that we can query for a signature.
- */
+#ifdef CONFIG_MGEODE_LX
+extern int geode_has_vsa2(void);
+#else
 static inline int geode_has_vsa2(void)
 {
-	outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
-	outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
-
-	return (inw(VSA_VRC_DATA) == VSA_SIG);
+	return 0;
 }
+#endif
 
 /* MFGPTs */
 
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
index da2adb4..6b722d3 100644
--- a/include/asm-x86/i387.h
+++ b/include/asm-x86/i387.h
@@ -175,7 +175,15 @@
  */
 static inline int restore_i387(struct _fpstate __user *buf)
 {
-	set_used_math();
+	struct task_struct *tsk = current;
+	int err;
+
+	if (!used_math()) {
+		err = init_fpu(tsk);
+		if (err)
+			return err;
+	}
+
 	if (!(task_thread_info(current)->status & TS_USEDFPU)) {
 		clts();
 		task_thread_info(current)->status |= TS_USEDFPU;
diff --git a/include/asm-x86/pat.h b/include/asm-x86/pat.h
index 8b822b5..88f60cc 100644
--- a/include/asm-x86/pat.h
+++ b/include/asm-x86/pat.h
@@ -4,7 +4,13 @@
 
 #include <linux/types.h>
 
+#ifdef CONFIG_X86_PAT
 extern int pat_wc_enabled;
+extern void validate_pat_support(struct cpuinfo_x86 *c);
+#else
+static const int pat_wc_enabled = 0;
+static inline void validate_pat_support(struct cpuinfo_x86 *c) { }
+#endif
 
 extern void pat_init(void);
 
@@ -12,5 +18,7 @@
 		unsigned long req_type, unsigned long *ret_type);
 extern int free_memtype(u64 start, u64 end);
 
+extern void pat_disable(char *reason);
+
 #endif
 
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 801b31f..55c3a0e 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -57,7 +57,8 @@
 #define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED |	\
 			 _PAGE_DIRTY)
 
-#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_PCD | _PAGE_PWT |		\
+			 _PAGE_ACCESSED | _PAGE_DIRTY)
 
 #define _PAGE_CACHE_MASK	(_PAGE_PCD | _PAGE_PWT)
 #define _PAGE_CACHE_WB		(0)
@@ -288,12 +289,21 @@
 	 * Chop off the NX bit (if present), and add the NX portion of
 	 * the newprot (if present):
 	 */
-	val &= _PAGE_CHG_MASK & ~_PAGE_NX;
-	val |= pgprot_val(newprot) & __supported_pte_mask;
+	val &= _PAGE_CHG_MASK;
+	val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask;
 
 	return __pte(val);
 }
 
+/* mprotect needs to preserve PAT bits when updating vm_page_prot */
+#define pgprot_modify pgprot_modify
+static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
+{
+	pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK;
+	pgprotval_t addbits = pgprot_val(newprot);
+	return __pgprot(preservebits | addbits);
+}
+
 #define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX))
 
 #define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
index 577ab79..d7f0403 100644
--- a/include/asm-x86/pgtable_32.h
+++ b/include/asm-x86/pgtable_32.h
@@ -88,14 +88,7 @@
 /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
 #define pmd_none(x)	(!(unsigned long)pmd_val((x)))
 #define pmd_present(x)	(pmd_val((x)) & _PAGE_PRESENT)
-
-extern int pmd_bad(pmd_t pmd);
-
-#define pmd_bad_v1(x)							\
-	(_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER)))
-#define	pmd_bad_v2(x)							\
-	(_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER |	\
-					    _PAGE_PSE | _PAGE_NX)))
+#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
 
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index a3bbf87..efe83dc 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -158,14 +158,12 @@
 
 static inline unsigned long pud_bad(pud_t pud)
 {
-	return pud_val(pud) &
-		~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX);
+	return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
 }
 
 static inline unsigned long pmd_bad(pmd_t pmd)
 {
-	return pmd_val(pmd) &
-		~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX);
+	return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
 }
 
 #define pte_none(x)	(!pte_val((x)))
diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h
index bc6376f..21e89bf 100644
--- a/include/asm-x86/spinlock.h
+++ b/include/asm-x86/spinlock.h
@@ -20,18 +20,8 @@
  */
 
 #ifdef CONFIG_X86_32
-typedef char _slock_t;
-# define LOCK_INS_DEC "decb"
-# define LOCK_INS_XCH "xchgb"
-# define LOCK_INS_MOV "movb"
-# define LOCK_INS_CMP "cmpb"
 # define LOCK_PTR_REG "a"
 #else
-typedef int _slock_t;
-# define LOCK_INS_DEC "decl"
-# define LOCK_INS_XCH "xchgl"
-# define LOCK_INS_MOV "movl"
-# define LOCK_INS_CMP "cmpl"
 # define LOCK_PTR_REG "D"
 #endif
 
@@ -66,14 +56,14 @@
 #if (NR_CPUS < 256)
 static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
 {
-	int tmp = *(volatile signed int *)(&(lock)->slock);
+	int tmp = ACCESS_ONCE(lock->slock);
 
 	return (((tmp >> 8) & 0xff) != (tmp & 0xff));
 }
 
 static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
 {
-	int tmp = *(volatile signed int *)(&(lock)->slock);
+	int tmp = ACCESS_ONCE(lock->slock);
 
 	return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1;
 }
@@ -130,14 +120,14 @@
 #else
 static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
 {
-	int tmp = *(volatile signed int *)(&(lock)->slock);
+	int tmp = ACCESS_ONCE(lock->slock);
 
 	return (((tmp >> 16) & 0xffff) != (tmp & 0xffff));
 }
 
 static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
 {
-	int tmp = *(volatile signed int *)(&(lock)->slock);
+	int tmp = ACCESS_ONCE(lock->slock);
 
 	return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1;
 }
diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h
index 4f35a0f..dcf3f81 100644
--- a/include/asm-x86/topology.h
+++ b/include/asm-x86/topology.h
@@ -25,6 +25,16 @@
 #ifndef _ASM_X86_TOPOLOGY_H
 #define _ASM_X86_TOPOLOGY_H
 
+#ifdef CONFIG_X86_32
+# ifdef CONFIG_X86_HT
+#  define ENABLE_TOPO_DEFINES
+# endif
+#else
+# ifdef CONFIG_SMP
+#  define ENABLE_TOPO_DEFINES
+# endif
+#endif
+
 #ifdef CONFIG_NUMA
 #include <linux/cpumask.h>
 #include <asm/mpspec.h>
@@ -130,10 +140,6 @@
 extern unsigned long node_remap_size[];
 #define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid])
 
-# ifdef CONFIG_X86_HT
-#  define ENABLE_TOPO_DEFINES
-# endif
-
 # define SD_CACHE_NICE_TRIES	1
 # define SD_IDLE_IDX		1
 # define SD_NEWIDLE_IDX		2
@@ -141,10 +147,6 @@
 
 #else
 
-# ifdef CONFIG_SMP
-#  define ENABLE_TOPO_DEFINES
-# endif
-
 # define SD_CACHE_NICE_TRIES	2
 # define SD_IDLE_IDX		2
 # define SD_NEWIDLE_IDX		2
diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h
index 82ad34d..ba03d5a 100644
--- a/include/asm-xtensa/param.h
+++ b/include/asm-xtensa/param.h
@@ -15,6 +15,8 @@
 # define HZ		CONFIG_HZ	/* internal timer frequency */
 # define USER_HZ	100		/* for user interfaces in "ticks" */
 # define CLOCKS_PER_SEC (USER_HZ)	/* frequnzy at which times() counts */
+#else
+# define HZ		100
 #endif
 
 #define EXEC_PAGESIZE	4096
diff --git a/include/linux/atm.h b/include/linux/atm.h
index 60136684..c791ddd 100644
--- a/include/linux/atm.h
+++ b/include/linux/atm.h
@@ -16,14 +16,11 @@
  * documentation. Do not change them.
  */
 
-#ifdef __KERNEL__
-#include <linux/socket.h>
-#include <linux/types.h>
-#endif
 #include <linux/compiler.h>
 #include <linux/atmapi.h>
 #include <linux/atmsap.h>
 #include <linux/atmioc.h>
+#include <linux/types.h>
 
 
 /* general ATM constants */
@@ -212,7 +209,7 @@
         char		pub[ATM_E164_LEN+1]; /* public address (E.164) */
     					/* unused addresses must be bzero'ed */
 	char		lij_type;	/* role in LIJ call; one of ATM_LIJ* */
-	uint32_t	lij_id;		/* LIJ call identifier */
+	__u32	lij_id;		/* LIJ call identifier */
     } sas_addr __ATM_API_ALIGN;		/* SVC address */
 };
 
diff --git a/include/linux/atm_tcp.h b/include/linux/atm_tcp.h
index 18787f9..375638f 100644
--- a/include/linux/atm_tcp.h
+++ b/include/linux/atm_tcp.h
@@ -8,11 +8,9 @@
 #define LINUX_ATM_TCP_H
 
 #include <linux/atmapi.h>
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#endif
+#include <linux/atm.h>
 #include <linux/atmioc.h>
+#include <linux/types.h>
 
 
 /*
@@ -20,9 +18,9 @@
  */
 
 struct atmtcp_hdr {
-	uint16_t	vpi;
-	uint16_t	vci;
-	uint32_t	length;		/* ... of data part */
+	__u16	vpi;
+	__u16	vci;
+	__u32	length;		/* ... of data part */
 };
 
 /*
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 43b406d..1abfe66 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -110,7 +110,6 @@
 
 extern int bitmap_scnprintf(char *buf, unsigned int len,
 			const unsigned long *src, int nbits);
-extern int bitmap_scnprintf_len(unsigned int len);
 extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
 			unsigned long *dst, int nbits);
 extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index dcae0c8..c8bd2da 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -182,4 +182,16 @@
 # define __section(S) __attribute__ ((__section__(#S)))
 #endif
 
+/*
+ * Prevent the compiler from merging or refetching accesses.  The compiler
+ * is also forbidden from reordering successive instances of ACCESS_ONCE(),
+ * but only when the compiler is aware of some particular ordering.  One way
+ * to make the compiler aware of ordering is to put the two invocations of
+ * ACCESS_ONCE() in different C statements.
+ *
+ * This macro does absolutely -nothing- to prevent the CPU from reordering,
+ * merging, or refetching absolutely anything at any time.
+ */
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
 #endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 9650806..5df3db5 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -289,13 +289,6 @@
 	return bitmap_scnprintf(buf, len, srcp->bits, nbits);
 }
 
-#define cpumask_scnprintf_len(len) \
-			__cpumask_scnprintf_len((len))
-static inline int __cpumask_scnprintf_len(int len)
-{
-	return bitmap_scnprintf_len(len);
-}
-
 #define cpumask_parse_user(ubuf, ulen, dst) \
 			__cpumask_parse_user((ubuf), (ulen), &(dst), NR_CPUS)
 static inline int __cpumask_parse_user(const char __user *buf, int len,
diff --git a/include/linux/device.h b/include/linux/device.h
index 8c23e3d..15e9fa3 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -183,7 +183,6 @@
 	struct module		*owner;
 
 	struct kset		subsys;
-	struct list_head	children;
 	struct list_head	devices;
 	struct list_head	interfaces;
 	struct kset		class_dirs;
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index de8387b..f5abd13 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -33,6 +33,19 @@
 	 * 32 bit parent directory inode number.
 	 */
 	FILEID_INO32_GEN_PARENT = 2,
+
+	/*
+	 * 32 bit block number, 16 bit partition reference,
+	 * 16 bit unused, 32 bit generation number.
+	 */
+	FILEID_UDF_WITHOUT_PARENT = 0x51,
+
+	/*
+	 * 32 bit block number, 16 bit partition reference,
+	 * 16 bit unused, 32 bit generation number,
+	 * 32 bit parent block number, 32 bit parent generation number
+	 */
+	FILEID_UDF_WITH_PARENT = 0x52,
 };
 
 struct fid {
@@ -43,6 +56,14 @@
 			u32 parent_ino;
 			u32 parent_gen;
 		} i32;
+ 		struct {
+ 			u32 block;
+ 			u16 partref;
+ 			u16 parent_partref;
+ 			u32 generation;
+ 			u32 parent_block;
+ 			u32 parent_generation;
+ 		} udf;
 		__u32 raw[0];
 	};
 };
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a1ba005..f413085 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1289,17 +1289,12 @@
 extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
 		unsigned long, loff_t *);
 
-/*
- * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called
- * without the big kernel lock held in all filesystems.
- */
 struct super_operations {
    	struct inode *(*alloc_inode)(struct super_block *sb);
 	void (*destroy_inode)(struct inode *);
 
    	void (*dirty_inode) (struct inode *);
 	int (*write_inode) (struct inode *, int);
-	void (*put_inode) (struct inode *);
 	void (*drop_inode) (struct inode *);
 	void (*delete_inode) (struct inode *);
 	void (*put_super) (struct super_block *);
@@ -1821,7 +1816,6 @@
 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 *);
 
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 5c86f11..d482821 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -109,6 +109,7 @@
 #define FUSE_POSIX_LOCKS	(1 << 1)
 #define FUSE_FILE_OPS		(1 << 2)
 #define FUSE_ATOMIC_O_TRUNC	(1 << 3)
+#define FUSE_BIG_WRITES		(1 << 5)
 
 /**
  * Release flags
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index ecd2bf6..ae7aec3 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -178,17 +178,17 @@
 
 static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)	{
 	int i;
+
 	for_each_possible_cpu(i)
 		memset(per_cpu_ptr(gendiskp->dkstats, i), value,
-				sizeof (struct disk_stats));
+				sizeof(struct disk_stats));
 }		
 
 #define __part_stat_add(part, field, addnd)				\
 	(per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd)
 
-#define __all_stat_add(gendiskp, field, addnd, sector)		\
+#define __all_stat_add(gendiskp, part, field, addnd, sector)	\
 ({								\
-	struct hd_struct *part = get_part(gendiskp, sector);	\
 	if (part)						\
 		__part_stat_add(part, field, addnd);		\
 	__disk_stat_add(gendiskp, field, addnd);		\
@@ -203,11 +203,13 @@
 	res;								\
 })
 
-static inline void part_stat_set_all(struct hd_struct *part, int value)	{
+static inline void part_stat_set_all(struct hd_struct *part, int value)
+{
 	int i;
+
 	for_each_possible_cpu(i)
 		memset(per_cpu_ptr(part->dkstats, i), value,
-		       sizeof(struct disk_stats));
+				sizeof(struct disk_stats));
 }
 				
 #else /* !CONFIG_SMP */
@@ -223,9 +225,8 @@
 #define __part_stat_add(part, field, addnd) \
 	(part->dkstats.field += addnd)
 
-#define __all_stat_add(gendiskp, field, addnd, sector)		\
+#define __all_stat_add(gendiskp, part, field, addnd, sector)	\
 ({								\
-	struct hd_struct *part = get_part(gendiskp, sector);	\
 	if (part)						\
 		part->dkstats.field += addnd;			\
 	__disk_stat_add(gendiskp, field, addnd);		\
@@ -276,10 +277,10 @@
 #define part_stat_sub(gendiskp, field, subnd) \
 		part_stat_add(gendiskp, field, -subnd)
 
-#define all_stat_add(gendiskp, field, addnd, sector)		\
+#define all_stat_add(gendiskp, part, field, addnd, sector)	\
 	do {							\
 		preempt_disable();				\
-		__all_stat_add(gendiskp, field, addnd, sector);	\
+		__all_stat_add(gendiskp, part, field, addnd, sector);	\
 		preempt_enable();				\
 	} while (0)
 
@@ -288,15 +289,15 @@
 #define all_stat_dec(gendiskp, field, sector) \
 		all_stat_add(gendiskp, field, -1, sector)
 
-#define __all_stat_inc(gendiskp, field, sector) \
-		__all_stat_add(gendiskp, field, 1, sector)
-#define all_stat_inc(gendiskp, field, sector) \
-		all_stat_add(gendiskp, field, 1, sector)
+#define __all_stat_inc(gendiskp, part, field, sector) \
+		__all_stat_add(gendiskp, part, field, 1, sector)
+#define all_stat_inc(gendiskp, part, field, sector) \
+		all_stat_add(gendiskp, part, field, 1, sector)
 
-#define __all_stat_sub(gendiskp, field, subnd, sector) \
-		__all_stat_add(gendiskp, field, -subnd, sector)
-#define all_stat_sub(gendiskp, field, subnd, sector) \
-		all_stat_add(gendiskp, field, -subnd, sector)
+#define __all_stat_sub(gendiskp, part, field, subnd, sector) \
+		__all_stat_add(gendiskp, part, field, -subnd, sector)
+#define all_stat_sub(gendiskp, part, field, subnd, sector) \
+		all_stat_add(gendiskp, part, field, -subnd, sector)
 
 /* Inlines to alloc and free disk stats in struct gendisk */
 #ifdef  CONFIG_SMP
@@ -524,7 +525,7 @@
 #define ADDPART_FLAG_RAID	1
 #define ADDPART_FLAG_WHOLEDISK	2
 
-extern dev_t blk_lookup_devt(const char *name);
+extern dev_t blk_lookup_devt(const char *name, int part);
 extern char *disk_name (struct gendisk *hd, int part, char *buf);
 
 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
@@ -552,7 +553,7 @@
 
 static inline void printk_all_partitions(void) { }
 
-static inline dev_t blk_lookup_devt(const char *name)
+static inline dev_t blk_lookup_devt(const char *name, int part)
 {
 	dev_t devt = MKDEV(0, 0);
 	return devt;
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 897f723..181006c 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -72,6 +72,14 @@
 #define in_softirq()		(softirq_count())
 #define in_interrupt()		(irq_count())
 
+#if defined(CONFIG_PREEMPT)
+# define PREEMPT_INATOMIC_BASE kernel_locked()
+# define PREEMPT_CHECK_OFFSET 1
+#else
+# define PREEMPT_INATOMIC_BASE 0
+# define PREEMPT_CHECK_OFFSET 0
+#endif
+
 /*
  * Are we running in atomic context?  WARNING: this macro cannot
  * always detect atomic context; in particular, it cannot know about
@@ -79,17 +87,11 @@
  * used in the general case to determine whether sleeping is possible.
  * Do not use in_atomic() in driver code.
  */
-#define in_atomic()		((preempt_count() & ~PREEMPT_ACTIVE) != 0)
-
-#ifdef CONFIG_PREEMPT
-# define PREEMPT_CHECK_OFFSET 1
-#else
-# define PREEMPT_CHECK_OFFSET 0
-#endif
+#define in_atomic()	((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_INATOMIC_BASE)
 
 /*
  * Check whether we were atomic before we did preempt_disable():
- * (used by the scheduler)
+ * (used by the scheduler, *after* releasing the kernel lock)
  */
 #define in_atomic_preempt_off() \
 		((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index cb63da5..6716ec8 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -262,7 +262,7 @@
  * client handles for the extra addresses.
  */
 extern struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type);
+i2c_new_dummy(struct i2c_adapter *adap, u16 address);
 
 extern void i2c_unregister_device(struct i2c_client *);
 
diff --git a/include/linux/ide.h b/include/linux/ide.h
index b0135b0..f8f195c 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -965,7 +965,6 @@
 void ide_tf_dump(const char *, struct ide_taskfile *);
 
 extern void SELECT_DRIVE(ide_drive_t *);
-extern void SELECT_MASK(ide_drive_t *, int);
 
 extern int drive_is_ready(ide_drive_t *);
 
@@ -1058,8 +1057,8 @@
 	IDE_HFLAG_NO_SET_MODE		= (1 << 9),
 	/* trust BIOS for programming chipset/device for DMA */
 	IDE_HFLAG_TRUST_BIOS_FOR_DMA	= (1 << 10),
-	/* host uses VDMA (tied with IDE_HFLAG_CS5520 for now) */
-	IDE_HFLAG_VDMA			= (1 << 11),
+	/* host is CS5510/CS5520 */
+	IDE_HFLAG_CS5520		= (1 << 11),
 	/* ATAPI DMA is unsupported */
 	IDE_HFLAG_NO_ATAPI_DMA		= (1 << 12),
 	/* set if host is a "non-bootable" controller */
@@ -1070,8 +1069,6 @@
 	IDE_HFLAG_NO_AUTODMA		= (1 << 15),
 	/* host uses MMIO */
 	IDE_HFLAG_MMIO			= (1 << 16),
-	/* host is CS5510/CS5520 */
-	IDE_HFLAG_CS5520		= IDE_HFLAG_VDMA,
 	/* no LBA48 */
 	IDE_HFLAG_NO_LBA48		= (1 << 17),
 	/* no LBA48 DMA */
@@ -1101,6 +1098,8 @@
 	IDE_HFLAG_NO_IO_32BIT		= (1 << 30),
 	/* never unmask IRQs */
 	IDE_HFLAG_NO_UNMASK_IRQS	= (1 << 31),
+	/* host uses VDMA (disabled for now) */
+	IDE_HFLAG_VDMA			= 0,
 };
 
 #ifdef CONFIG_BLK_DEV_OFFBOARD
diff --git a/include/linux/io.h b/include/linux/io.h
index 3a03a36..6c7f0ba 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -65,5 +65,6 @@
 void devm_iounmap(struct device *dev, void __iomem *addr);
 int check_signature(const volatile void __iomem *io_addr,
 			const unsigned char *signature, int length);
+void devm_ioremap_release(struct device *dev, void *res);
 
 #endif /* _LINUX_IO_H */
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
index 2a3bb1b..f98a656 100644
--- a/include/linux/ioprio.h
+++ b/include/linux/ioprio.h
@@ -68,6 +68,20 @@
 }
 
 /*
+ * This is for the case where the task hasn't asked for a specific IO class.
+ * Check for idle and rt task process, and return appropriate IO class.
+ */
+static inline int task_nice_ioclass(struct task_struct *task)
+{
+	if (task->policy == SCHED_IDLE)
+		return IOPRIO_CLASS_IDLE;
+	else if (task->policy == SCHED_FIFO || task->policy == SCHED_RR)
+		return IOPRIO_CLASS_RT;
+	else
+		return IOPRIO_CLASS_BE;
+}
+
+/*
  * For inheritance, return the highest of the two given priorities
  */
 extern int ioprio_best(unsigned short aprio, unsigned short bprio);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4d46e29..792bf0a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -276,7 +276,17 @@
 				const void *buf, size_t len, bool ascii);
 extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
 			const void *buf, size_t len);
-#define hex_asc(x)	"0123456789abcdef"[x]
+
+extern const char hex_asc[];
+#define hex_asc_lo(x)	hex_asc[((x) & 0x0f)]
+#define hex_asc_hi(x)	hex_asc[((x) & 0xf0) >> 4]
+
+static inline char *pack_hex_byte(char *buf, u8 byte)
+{
+	*buf++ = hex_asc_hi(byte);
+	*buf++ = hex_asc_lo(byte);
+	return buf;
+}
 
 #define pr_emerg(fmt, arg...) \
 	printk(KERN_EMERG fmt, ##arg)
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index 9757b1a..6adcc29 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -261,10 +261,12 @@
 
 extern struct kgdb_arch		arch_kgdb_ops;
 
+extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs);
+
 extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops);
 extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops);
 
-extern int kgdb_hex2long(char **ptr, long *long_val);
+extern int kgdb_hex2long(char **ptr, unsigned long *long_val);
 extern int kgdb_mem2hex(char *mem, char *buf, int count);
 extern int kgdb_hex2mem(char *buf, char *mem, int count);
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index d1dfe87..0f17643 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1039,6 +1039,7 @@
 
 extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
+extern void ata_eh_analyze_ncq_error(struct ata_link *link);
 
 extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
 		      ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
@@ -1381,6 +1382,18 @@
 	return *(struct ata_port **)&host->hostdata[0];
 }
 
+static inline int ata_check_ready(u8 status)
+{
+	if (!(status & ATA_BUSY))
+		return 1;
+
+	/* 0xff indicates either no device or device not ready */
+	if (status == 0xff)
+		return -ENODEV;
+
+	return 0;
+}
+
 
 /**************************************************************************
  * PMP - drivers/ata/libata-pmp.c
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index eb7c16c..02a27ae 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -226,8 +226,17 @@
 	rwlock_t		ioctx_list_lock;	/* aio lock */
 	struct kioctx		*ioctx_list;
 #ifdef CONFIG_MM_OWNER
-	struct task_struct *owner;	/* The thread group leader that */
-					/* owns the mm_struct.		*/
+	/*
+	 * "owner" points to a task that is regarded as the canonical
+	 * user/owner of this mm. All of the following must be true in
+	 * order for it to be changed:
+	 *
+	 * current == mm->owner
+	 * current->mm != mm
+	 * new_owner->mm == mm
+	 * new_owner->alloc_lock is held
+	 */
+	struct task_struct *owner;
 #endif
 
 #ifdef CONFIG_PROC_FS
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
index 30e11aa..a15cdd4 100644
--- a/include/linux/mv643xx_eth.h
+++ b/include/linux/mv643xx_eth.h
@@ -1,19 +1,31 @@
 /*
  * MV-643XX ethernet platform device data definition file.
  */
+
 #ifndef __LINUX_MV643XX_ETH_H
 #define __LINUX_MV643XX_ETH_H
 
-#define MV643XX_ETH_SHARED_NAME		"mv643xx_eth_shared"
-#define MV643XX_ETH_NAME		"mv643xx_eth"
+#include <linux/mbus.h>
+
+#define MV643XX_ETH_SHARED_NAME		"mv643xx_eth"
+#define MV643XX_ETH_NAME		"mv643xx_eth_port"
 #define MV643XX_ETH_SHARED_REGS		0x2000
 #define MV643XX_ETH_SHARED_REGS_SIZE	0x2000
 #define MV643XX_ETH_BAR_4		0x2220
 #define MV643XX_ETH_SIZE_REG_4		0x2224
 #define MV643XX_ETH_BASE_ADDR_ENABLE_REG	0x2290
 
+struct mv643xx_eth_shared_platform_data {
+	struct mbus_dram_target_info	*dram;
+	unsigned int	t_clk;
+};
+
 struct mv643xx_eth_platform_data {
+	struct platform_device	*shared;
 	int		port_number;
+
+	struct platform_device	*shared_smi;
+
 	u16		force_phy_addr;	/* force override if phy_addr == 0 */
 	u16		phy_addr;
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7c1d446..b11e6e1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -93,14 +93,16 @@
  *	used.
  */
  
-#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR)
-#define LL_MAX_HEADER	32
+#if defined(CONFIG_WLAN_80211) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+# if defined(CONFIG_MAC80211_MESH)
+#  define LL_MAX_HEADER 128
+# else
+#  define LL_MAX_HEADER 96
+# endif
+#elif defined(CONFIG_TR)
+# define LL_MAX_HEADER 48
 #else
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
-#define LL_MAX_HEADER	96
-#else
-#define LL_MAX_HEADER	48
-#endif
+# define LL_MAX_HEADER 32
 #endif
 
 #if !defined(CONFIG_NET_IPIP) && !defined(CONFIG_NET_IPIP_MODULE) && \
@@ -244,11 +246,16 @@
  *
  * We could use other alignment values, but we must maintain the
  * relationship HH alignment <= LL alignment.
+ *
+ * LL_ALLOCATED_SPACE also takes into account the tailroom the device
+ * may need.
  */
 #define LL_RESERVED_SPACE(dev) \
-	(((dev)->hard_header_len&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+	((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 #define LL_RESERVED_SPACE_EXTRA(dev,extra) \
-	((((dev)->hard_header_len+extra)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+	((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+#define LL_ALLOCATED_SPACE(dev) \
+	((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 
 struct header_ops {
 	int	(*create) (struct sk_buff *skb, struct net_device *dev,
@@ -567,6 +574,13 @@
 	unsigned short		type;	/* interface hardware type	*/
 	unsigned short		hard_header_len;	/* hardware hdr length	*/
 
+	/* extra head- and tailroom the hardware may need, but not in all cases
+	 * can this be guaranteed, especially tailroom. Some cases also use
+	 * LL_MAX_HEADER instead to allocate the skb.
+	 */
+	unsigned short		needed_headroom;
+	unsigned short		needed_tailroom;
+
 	struct net_device	*master; /* Pointer to master device of a group,
 					  * which this device is member of.
 					  */
@@ -715,6 +729,9 @@
 	struct net		*nd_net;
 #endif
 
+	/* mid-layer private */
+	void			*ml_priv;
+
 	/* bridge stuff */
 	struct net_bridge_port	*br_port;
 	/* macvlan */
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
index 5da04e5..23aa2ec 100644
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -7,6 +7,7 @@
 
 struct nf_ct_sip_master {
 	unsigned int	register_cseq;
+	unsigned int	invite_cseq;
 };
 
 enum sip_expectation_classes {
diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h
index 2e5a967..bd2a870 100644
--- a/include/linux/of_i2c.h
+++ b/include/linux/of_i2c.h
@@ -14,11 +14,7 @@
 
 #include <linux/i2c.h>
 
-#ifdef CONFIG_OF_I2C
-
 void of_register_i2c_devices(struct i2c_adapter *adap,
 			     struct device_node *adap_node);
 
-#endif /* CONFIG_OF_I2C */
-
 #endif /* __LINUX_OF_I2C_H */
diff --git a/include/linux/parser.h b/include/linux/parser.h
index 26b2bdf..7dcd050 100644
--- a/include/linux/parser.h
+++ b/include/linux/parser.h
@@ -29,5 +29,5 @@
 int match_int(substring_t *, int *result);
 int match_octal(substring_t *, int *result);
 int match_hex(substring_t *, int *result);
-void match_strcpy(char *, const substring_t *);
+size_t match_strlcpy(char *, const substring_t *, size_t);
 char *match_strdup(const substring_t *);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 96acd0d..509159b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -44,6 +44,7 @@
 #include <linux/mod_devicetable.h>
 
 #include <linux/types.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/list.h>
 #include <linux/compiler.h>
@@ -474,7 +475,7 @@
 void pci_bus_add_devices(struct pci_bus *bus);
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
 				      struct pci_ops *ops, void *sysdata);
-static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
+static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
 					   void *sysdata)
 {
 	struct pci_bus *root_bus;
@@ -666,7 +667,7 @@
 
 void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
 		  void *userdata);
-int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix);
+int pci_cfg_space_size_ext(struct pci_dev *dev);
 int pci_cfg_space_size(struct pci_dev *dev);
 unsigned char pci_bus_max_busnr(struct pci_bus *bus);
 
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index d746a2a..4cdd393 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -13,8 +13,14 @@
 	__attribute__((__section__(".data.percpu")))			\
 	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
 
+#ifdef MODULE
+#define SHARED_ALIGNED_SECTION ".data.percpu"
+#else
+#define SHARED_ALIGNED_SECTION ".data.percpu.shared_aligned"
+#endif
+
 #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name)			\
-	__attribute__((__section__(".data.percpu.shared_aligned")))	\
+	__attribute__((__section__(SHARED_ALIGNED_SECTION)))		\
 	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name		\
 	____cacheline_aligned_in_smp
 #else
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 02df20f..7224c40 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -412,6 +412,8 @@
 void mdiobus_unregister(struct mii_bus *bus);
 void phy_sanitize_settings(struct phy_device *phydev);
 int phy_stop_interrupts(struct phy_device *phydev);
+int phy_enable_interrupts(struct phy_device *phydev);
+int phy_disable_interrupts(struct phy_device *phydev);
 
 static inline int phy_read_status(struct phy_device *phydev) {
 	return phydev->drv->read_status(phydev);
@@ -447,5 +449,8 @@
 		int (*run)(struct phy_device *));
 int phy_scan_fixups(struct phy_device *phydev);
 
+int __init mdio_bus_init(void);
+void mdio_bus_exit(void);
+
 extern struct bus_type mdio_bus_type;
 #endif /* __PHY_H */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 8082d65..d42dbec 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -131,18 +131,6 @@
  */
 #define rcu_read_unlock_bh() __rcu_read_unlock_bh()
 
-/*
- * Prevent the compiler from merging or refetching accesses.  The compiler
- * is also forbidden from reordering successive instances of ACCESS_ONCE(),
- * but only when the compiler is aware of some particular ordering.  One way
- * to make the compiler aware of ordering is to put the two invocations of
- * ACCESS_ONCE() in different C statements.
- *
- * This macro does absolutely -nothing- to prevent the CPU from reordering,
- * merging, or refetching absolutely anything at any time.
- */
-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
-
 /**
  * rcu_dereference - fetch an RCU-protected pointer in an
  * RCU read-side critical section.  This pointer may later
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 03c2380..5395a61 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -158,6 +158,8 @@
 }
 #endif
 
+extern unsigned long long time_sync_thresh;
+
 /*
  * Task state bitmask. NOTE! These bits are also
  * encoded in fs/proc/array.c: get_task_state().
@@ -1551,6 +1553,35 @@
 
 extern unsigned long long sched_clock(void);
 
+#ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
+static inline void sched_clock_init(void)
+{
+}
+
+static inline u64 sched_clock_cpu(int cpu)
+{
+	return sched_clock();
+}
+
+static inline void sched_clock_tick(void)
+{
+}
+
+static inline void sched_clock_idle_sleep_event(void)
+{
+}
+
+static inline void sched_clock_idle_wakeup_event(u64 delta_ns)
+{
+}
+#else
+extern void sched_clock_init(void);
+extern u64 sched_clock_cpu(int cpu);
+extern void sched_clock_tick(void);
+extern void sched_clock_idle_sleep_event(void);
+extern void sched_clock_idle_wakeup_event(u64 delta_ns);
+#endif
+
 /*
  * For kernel-internal use: high-speed (but slightly incorrect) per-cpu
  * clock constructed from sched_clock():
@@ -1977,6 +2008,11 @@
 	clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED);
 }
 
+static inline int test_tsk_need_resched(struct task_struct *tsk)
+{
+	return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED));
+}
+
 static inline int signal_pending(struct task_struct *p)
 {
 	return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
@@ -2001,13 +2037,13 @@
  * cond_resched_lock() will drop the spinlock before scheduling,
  * cond_resched_softirq() will enable bhs before scheduling.
  */
-#ifdef CONFIG_PREEMPT
+extern int _cond_resched(void);
+#ifdef CONFIG_PREEMPT_BKL
 static inline int cond_resched(void)
 {
 	return 0;
 }
 #else
-extern int _cond_resched(void);
 static inline int cond_resched(void)
 {
 	return _cond_resched();
@@ -2015,6 +2051,10 @@
 #endif
 extern int cond_resched_lock(spinlock_t * lock);
 extern int cond_resched_softirq(void);
+static inline int cond_resched_bkl(void)
+{
+	return _cond_resched();
+}
 
 /*
  * Does a critical section need to be broken due to another
diff --git a/include/linux/usb/association.h b/include/linux/usb/association.h
new file mode 100644
index 0000000..07c5e3c
--- /dev/null
+++ b/include/linux/usb/association.h
@@ -0,0 +1,150 @@
+/*
+ * Wireless USB - Cable Based Association
+ *
+ * Copyright (C) 2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * 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.
+ *
+ */
+#ifndef __LINUX_USB_ASSOCIATION_H
+#define __LINUX_USB_ASSOCIATION_H
+
+
+/*
+ * Association attributes
+ *
+ * Association Models Supplement to WUSB 1.0 T[3-1]
+ *
+ * Each field in the structures has it's ID, it's length and then the
+ * value. This is the actual definition of the field's ID and its
+ * length.
+ */
+struct wusb_am_attr {
+	__u8 id;
+	__u8 len;
+};
+
+/* Different fields defined by the spec */
+#define WUSB_AR_AssociationTypeId	{ .id = 0x0000, .len =  2 }
+#define WUSB_AR_AssociationSubTypeId	{ .id = 0x0001, .len =  2 }
+#define WUSB_AR_Length			{ .id = 0x0002, .len =  4 }
+#define WUSB_AR_AssociationStatus	{ .id = 0x0004, .len =  4 }
+#define WUSB_AR_LangID			{ .id = 0x0008, .len =  2 }
+#define WUSB_AR_DeviceFriendlyName	{ .id = 0x000b, .len = 64 } /* max */
+#define WUSB_AR_HostFriendlyName	{ .id = 0x000c, .len = 64 } /* max */
+#define WUSB_AR_CHID			{ .id = 0x1000, .len = 16 }
+#define WUSB_AR_CDID			{ .id = 0x1001, .len = 16 }
+#define WUSB_AR_ConnectionContext	{ .id = 0x1002, .len = 48 }
+#define WUSB_AR_BandGroups		{ .id = 0x1004, .len =  2 }
+
+/* CBAF Control Requests (AMS1.0[T4-1] */
+enum {
+	CBAF_REQ_GET_ASSOCIATION_INFORMATION = 0x01,
+	CBAF_REQ_GET_ASSOCIATION_REQUEST,
+	CBAF_REQ_SET_ASSOCIATION_RESPONSE
+};
+
+/*
+ * CBAF USB-interface defitions
+ *
+ * No altsettings, one optional interrupt endpoint.
+ */
+enum {
+	CBAF_IFACECLASS    = 0xef,
+	CBAF_IFACESUBCLASS = 0x03,
+	CBAF_IFACEPROTOCOL = 0x01,
+};
+
+/* Association Information (AMS1.0[T4-3]) */
+struct wusb_cbaf_assoc_info {
+	__le16 Length;
+	__u8 NumAssociationRequests;
+	__le16 Flags;
+	__u8 AssociationRequestsArray[];
+} __attribute__((packed));
+
+/* Association Request (AMS1.0[T4-4]) */
+struct wusb_cbaf_assoc_request {
+	__u8 AssociationDataIndex;
+	__u8 Reserved;
+	__le16 AssociationTypeId;
+	__le16 AssociationSubTypeId;
+	__le32 AssociationTypeInfoSize;
+} __attribute__((packed));
+
+enum {
+	AR_TYPE_WUSB                    = 0x0001,
+	AR_TYPE_WUSB_RETRIEVE_HOST_INFO = 0x0000,
+	AR_TYPE_WUSB_ASSOCIATE          = 0x0001,
+};
+
+/* Association Attribute header (AMS1.0[3.8]) */
+struct wusb_cbaf_attr_hdr {
+	__le16 id;
+	__le16 len;
+} __attribute__((packed));
+
+/* Host Info (AMS1.0[T4-7]) (yeah, more headers and fields...) */
+struct wusb_cbaf_host_info {
+	struct wusb_cbaf_attr_hdr AssociationTypeId_hdr;
+	__le16 AssociationTypeId;
+	struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr;
+	__le16 AssociationSubTypeId;
+	struct wusb_cbaf_attr_hdr CHID_hdr;
+	struct wusb_ckhdid CHID;
+	struct wusb_cbaf_attr_hdr LangID_hdr;
+	__le16 LangID;
+	struct wusb_cbaf_attr_hdr HostFriendlyName_hdr;
+	__u8 HostFriendlyName[];
+} __attribute__((packed));
+
+/* Device Info (AMS1.0[T4-8])
+ *
+ * I still don't get this tag'n'header stuff for each goddamn
+ * field...
+ */
+struct wusb_cbaf_device_info {
+	struct wusb_cbaf_attr_hdr Length_hdr;
+	__le32 Length;
+	struct wusb_cbaf_attr_hdr CDID_hdr;
+	struct wusb_ckhdid CDID;
+	struct wusb_cbaf_attr_hdr BandGroups_hdr;
+	__le16 BandGroups;
+	struct wusb_cbaf_attr_hdr LangID_hdr;
+	__le16 LangID;
+	struct wusb_cbaf_attr_hdr DeviceFriendlyName_hdr;
+	__u8 DeviceFriendlyName[];
+} __attribute__((packed));
+
+/* Connection Context; CC_DATA - Success case (AMS1.0[T4-9]) */
+struct wusb_cbaf_cc_data {
+	struct wusb_cbaf_attr_hdr AssociationTypeId_hdr;
+	__le16 AssociationTypeId;
+	struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr;
+	__le16 AssociationSubTypeId;
+	struct wusb_cbaf_attr_hdr Length_hdr;
+	__le32 Length;
+	struct wusb_cbaf_attr_hdr ConnectionContext_hdr;
+	struct wusb_ckhdid CHID;
+	struct wusb_ckhdid CDID;
+	struct wusb_ckhdid CK;
+	struct wusb_cbaf_attr_hdr BandGroups_hdr;
+	__le16 BandGroups;
+} __attribute__((packed));
+
+/* CC_DATA - Failure case (AMS1.0[T4-10]) */
+struct wusb_cbaf_cc_data_fail {
+	struct wusb_cbaf_attr_hdr AssociationTypeId_hdr;
+	__le16 AssociationTypeId;
+	struct wusb_cbaf_attr_hdr AssociationSubTypeId_hdr;
+	__le16 AssociationSubTypeId;
+	struct wusb_cbaf_attr_hdr Length_hdr;
+	__le16 Length;
+	struct wusb_cbaf_attr_hdr AssociationStatus_hdr;
+	__u32 AssociationStatus;
+} __attribute__((packed));
+
+#endif	/* __LINUX_USB_ASSOCIATION_H */
diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h
index 4d0909e..79b9837 100644
--- a/include/linux/vermagic.h
+++ b/include/linux/vermagic.h
@@ -17,6 +17,11 @@
 #else
 #define MODULE_VERMAGIC_MODULE_UNLOAD ""
 #endif
+#ifdef CONFIG_MODVERSIONS
+#define MODULE_VERMAGIC_MODVERSIONS "modversions "
+#else
+#define MODULE_VERMAGIC_MODVERSIONS ""
+#endif
 #ifndef MODULE_ARCH_VERMAGIC
 #define MODULE_ARCH_VERMAGIC ""
 #endif
@@ -24,5 +29,6 @@
 #define VERMAGIC_STRING 						\
 	UTS_RELEASE " "							\
 	MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT 			\
-	MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC
+	MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS	\
+	MODULE_ARCH_VERMAGIC
 
diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h
index 347b6f8..8785622 100644
--- a/include/media/v4l2-i2c-drv-legacy.h
+++ b/include/media/v4l2-i2c-drv-legacy.h
@@ -31,6 +31,7 @@
 	int (*resume)(struct i2c_client *client);
 	int (*legacy_probe)(struct i2c_adapter *adapter);
 	int legacy_class;
+	const struct i2c_device_id *id_table;
 };
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data;
@@ -124,6 +125,7 @@
 	v4l2_i2c_driver.command = v4l2_i2c_data.command;
 	v4l2_i2c_driver.probe = v4l2_i2c_data.probe;
 	v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
+	v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table;
 	err = i2c_add_driver(&v4l2_i2c_driver);
 	if (err)
 		i2c_del_driver(&v4l2_i2c_driver_legacy);
diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h
index 7b6f06b..40ecef2 100644
--- a/include/media/v4l2-i2c-drv.h
+++ b/include/media/v4l2-i2c-drv.h
@@ -36,6 +36,7 @@
 	int (*resume)(struct i2c_client *client);
 	int (*legacy_probe)(struct i2c_adapter *adapter);
 	int legacy_class;
+	const struct i2c_device_id *id_table;
 };
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data;
@@ -53,6 +54,7 @@
 	v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
 	v4l2_i2c_driver.suspend = v4l2_i2c_data.suspend;
 	v4l2_i2c_driver.resume = v4l2_i2c_data.resume;
+	v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table;
 	return i2c_add_driver(&v4l2_i2c_driver);
 }
 
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 585eb44..b3d3e27 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -29,14 +29,31 @@
 
 #ifdef CONFIG_NET_9P_DEBUG
 
-#define P9_DEBUG_ERROR		(1<<0)
-#define P9_DEBUG_9P	        (1<<2)
-#define P9_DEBUG_VFS	        (1<<3)
-#define P9_DEBUG_CONV		(1<<4)
-#define P9_DEBUG_MUX		(1<<5)
-#define P9_DEBUG_TRANS		(1<<6)
-#define P9_DEBUG_SLABS	      	(1<<7)
-#define P9_DEBUG_FCALL		(1<<8)
+/**
+ * enum p9_debug_flags - bits for mount time debug parameter
+ * @P9_DEBUG_ERROR: more verbose error messages including original error string
+ * @P9_DEBUG_9P: 9P protocol tracing
+ * @P9_DEBUG_VFS: VFS API tracing
+ * @P9_DEBUG_CONV: protocol conversion tracing
+ * @P9_DEBUG_MUX: trace management of concurrent transactions
+ * @P9_DEBUG_TRANS: transport tracing
+ * @P9_DEBUG_SLABS: memory management tracing
+ * @P9_DEBUG_FCALL: verbose dump of protocol messages
+ *
+ * These flags are passed at mount time to turn on various levels of
+ * verbosity and tracing which will be output to the system logs.
+ */
+
+enum p9_debug_flags {
+	P9_DEBUG_ERROR = 	(1<<0),
+	P9_DEBUG_9P = 		(1<<2),
+	P9_DEBUG_VFS =		(1<<3),
+	P9_DEBUG_CONV =		(1<<4),
+	P9_DEBUG_MUX =		(1<<5),
+	P9_DEBUG_TRANS =	(1<<6),
+	P9_DEBUG_SLABS =      	(1<<7),
+	P9_DEBUG_FCALL =	(1<<8),
+};
 
 extern unsigned int p9_debug_level;
 
@@ -62,9 +79,47 @@
 		format , __FUNCTION__, task_pid_nr(current), ## arg); \
 } while (0)
 
+/**
+ * enum p9_msg_t - 9P message types
+ * @P9_TVERSION: version handshake request
+ * @P9_RVERSION: version handshake response
+ * @P9_TAUTH: request to establish authentication channel
+ * @P9_RAUTH: response with authentication information
+ * @P9_TATTACH: establish user access to file service
+ * @P9_RATTACH: response with top level handle to file hierarchy
+ * @P9_TERROR: not used
+ * @P9_RERROR: response for any failed request
+ * @P9_TFLUSH: request to abort a previous request
+ * @P9_RFLUSH: response when previous request has been cancelled
+ * @P9_TWALK: descend a directory hierarchy
+ * @P9_RWALK: response with new handle for position within hierarchy
+ * @P9_TOPEN: prepare a handle for I/O on an existing file
+ * @P9_ROPEN: response with file access information
+ * @P9_TCREATE: prepare a handle for I/O on a new file
+ * @P9_RCREATE: response with file access information
+ * @P9_TREAD: request to transfer data from a file or directory
+ * @P9_RREAD: response with data requested
+ * @P9_TWRITE: reuqest to transfer data to a file
+ * @P9_RWRITE: response with out much data was transfered to file
+ * @P9_TCLUNK: forget about a handle to an entity within the file system
+ * @P9_RCLUNK: response when server has forgotten about the handle
+ * @P9_TREMOVE: request to remove an entity from the hierarchy
+ * @P9_RREMOVE: response when server has removed the entity
+ * @P9_TSTAT: request file entity attributes
+ * @P9_RSTAT: response with file entity attributes
+ * @P9_TWSTAT: request to update file entity attributes
+ * @P9_RWSTAT: response when file entity attributes are updated
+ *
+ * There are 14 basic operations in 9P2000, paired as
+ * requests and responses.  The one special case is ERROR
+ * as there is no @P9_TERROR request for clients to transmit to
+ * the server, but the server may respond to any other request
+ * with an @P9_RERROR.
+ *
+ * See Also: http://plan9.bell-labs.com/sys/man/5/INDEX.html
+ */
 
-/* Message Types */
-enum {
+enum p9_msg_t {
 	P9_TVERSION = 100,
 	P9_RVERSION,
 	P9_TAUTH = 102,
@@ -95,30 +150,71 @@
 	P9_RWSTAT,
 };
 
-/* open modes */
-enum {
+/**
+ * enum p9_open_mode_t - 9P open modes
+ * @P9_OREAD: open file for reading only
+ * @P9_OWRITE: open file for writing only
+ * @P9_ORDWR: open file for reading or writing
+ * @P9_OEXEC: open file for execution
+ * @P9_OTRUNC: truncate file to zero-length before opening it
+ * @P9_OREXEC: close the file when an exec(2) system call is made
+ * @P9_ORCLOSE: remove the file when the file is closed
+ * @P9_OAPPEND: open the file and seek to the end
+ * @P9_OEXCL: only create a file, do not open it
+ *
+ * 9P open modes differ slightly from Posix standard modes.
+ * In particular, there are extra modes which specify different
+ * semantic behaviors than may be available on standard Posix
+ * systems.  For example, @P9_OREXEC and @P9_ORCLOSE are modes that
+ * most likely will not be issued from the Linux VFS client, but may
+ * be supported by servers.
+ *
+ * See Also: http://plan9.bell-labs.com/magic/man2html/2/open
+ */
+
+enum p9_open_mode_t {
 	P9_OREAD = 0x00,
 	P9_OWRITE = 0x01,
 	P9_ORDWR = 0x02,
 	P9_OEXEC = 0x03,
-	P9_OEXCL = 0x04,
 	P9_OTRUNC = 0x10,
 	P9_OREXEC = 0x20,
 	P9_ORCLOSE = 0x40,
 	P9_OAPPEND = 0x80,
+	P9_OEXCL = 0x1000,
 };
 
-/* permissions */
-enum {
+/**
+ * enum p9_perm_t - 9P permissions
+ * @P9_DMDIR: mode bite for directories
+ * @P9_DMAPPEND: mode bit for is append-only
+ * @P9_DMEXCL: mode bit for excluse use (only one open handle allowed)
+ * @P9_DMMOUNT: mode bite for mount points
+ * @P9_DMAUTH: mode bit for authentication file
+ * @P9_DMTMP: mode bit for non-backed-up files
+ * @P9_DMSYMLINK: mode bit for symbolic links (9P2000.u)
+ * @P9_DMLINK: mode bit for hard-link (9P2000.u)
+ * @P9_DMDEVICE: mode bit for device files (9P2000.u)
+ * @P9_DMNAMEDPIPE: mode bit for named pipe (9P2000.u)
+ * @P9_DMSOCKET: mode bit for socket (9P2000.u)
+ * @P9_DMSETUID: mode bit for setuid (9P2000.u)
+ * @P9_DMSETGID: mode bit for setgid (9P2000.u)
+ * @P9_DMSETVTX: mode bit for sticky bit (9P2000.u)
+ *
+ * 9P permissions differ slightly from Posix standard modes.
+ *
+ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
+ */
+enum p9_perm_t {
 	P9_DMDIR = 0x80000000,
 	P9_DMAPPEND = 0x40000000,
 	P9_DMEXCL = 0x20000000,
 	P9_DMMOUNT = 0x10000000,
 	P9_DMAUTH = 0x08000000,
 	P9_DMTMP = 0x04000000,
+/* 9P2000.u extensions */
 	P9_DMSYMLINK = 0x02000000,
 	P9_DMLINK = 0x01000000,
-	/* 9P2000.u extensions */
 	P9_DMDEVICE = 0x00800000,
 	P9_DMNAMEDPIPE = 0x00200000,
 	P9_DMSOCKET = 0x00100000,
@@ -127,8 +223,26 @@
 	P9_DMSETVTX = 0x00010000,
 };
 
-/* qid.types */
-enum {
+/**
+ * enum p9_qid_t - QID types
+ * @P9_QTDIR: directory
+ * @P9_QTAPPEND: append-only
+ * @P9_QTEXCL: excluse use (only one open handle allowed)
+ * @P9_QTMOUNT: mount points
+ * @P9_QTAUTH: authentication file
+ * @P9_QTTMP: non-backed-up files
+ * @P9_QTSYMLINK: symbolic links (9P2000.u)
+ * @P9_QTLINK: hard-link (9P2000.u)
+ * @P9_QTFILE: normal files
+ *
+ * QID types are a subset of permissions - they are primarily
+ * used to differentiate semantics for a file system entity via
+ * a jump-table.  Their value is also the most signifigant 16 bits
+ * of the permission_t
+ *
+ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
+ */
+enum p9_qid_t {
 	P9_QTDIR = 0x80,
 	P9_QTAPPEND = 0x40,
 	P9_QTEXCL = 0x20,
@@ -140,6 +254,7 @@
 	P9_QTFILE = 0x00,
 };
 
+/* 9P Magic Numbers */
 #define P9_NOTAG	(u16)(~0)
 #define P9_NOFID	(u32)(~0)
 #define P9_MAXWELEM	16
@@ -147,19 +262,69 @@
 /* ample room for Twrite/Rread header */
 #define P9_IOHDRSZ	24
 
+/**
+ * struct p9_str - length prefixed string type
+ * @len: length of the string
+ * @str: the string
+ *
+ * The protocol uses length prefixed strings for all
+ * string data, so we replicate that for our internal
+ * string members.
+ */
+
 struct p9_str {
 	u16 len;
 	char *str;
 };
 
-/* qids are the unique ID for a file (like an inode */
+/**
+ * struct p9_qid - file system entity information
+ * @type: 8-bit type &p9_qid_t
+ * @version: 16-bit monotonically incrementing version number
+ * @path: 64-bit per-server-unique ID for a file system element
+ *
+ * qids are identifiers used by 9P servers to track file system
+ * entities.  The type is used to differentiate semantics for operations
+ * on the entity (ie. read means something different on a directory than
+ * on a file).  The path provides a server unique index for an entity
+ * (roughly analogous to an inode number), while the version is updated
+ * every time a file is modified and can be used to maintain cache
+ * coherency between clients and serves.
+ * Servers will often differentiate purely synthetic entities by setting
+ * their version to 0, signaling that they should never be cached and
+ * should be accessed synchronously.
+ *
+ * See Also://plan9.bell-labs.com/magic/man2html/2/stat
+ */
+
 struct p9_qid {
 	u8 type;
 	u32 version;
 	u64 path;
 };
 
-/* Plan 9 file metadata (stat) structure */
+/**
+ * struct p9_stat - file system metadata information
+ * @size: length prefix for this stat structure instance
+ * @type: the type of the server (equivilent to a major number)
+ * @dev: the sub-type of the server (equivilent to a minor number)
+ * @qid: unique id from the server of type &p9_qid
+ * @mode: Plan 9 format permissions of type &p9_perm_t
+ * @atime: Last access/read time
+ * @mtime: Last modify/write time
+ * @length: file length
+ * @name: last element of path (aka filename) in type &p9_str
+ * @uid: owner name in type &p9_str
+ * @gid: group owner in type &p9_str
+ * @muid: last modifier in type &p9_str
+ * @extension: area used to encode extended UNIX support in type &p9_str
+ * @n_uid: numeric user id of owner (part of 9p2000.u extension)
+ * @n_gid: numeric group id (part of 9p2000.u extension)
+ * @n_muid: numeric user id of laster modifier (part of 9p2000.u extension)
+ *
+ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
+ */
+
 struct p9_stat {
 	u16 size;
 	u16 type;
@@ -179,10 +344,14 @@
 	u32 n_muid;			/* 9p2000.u extensions */
 };
 
-/* file metadata (stat) structure used to create Twstat message
-   The is similar to p9_stat, but the strings don't point to
-   the same memory block and should be freed separately
-*/
+/*
+ * file metadata (stat) structure used to create Twstat message
+ * The is identical to &p9_stat, but the strings don't point to
+ * the same memory block and should be freed separately
+ *
+ * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
+ */
+
 struct p9_wstat {
 	u16 size;
 	u16 type;
@@ -335,10 +504,20 @@
 struct p9_rwstat {
 };
 
-/*
-  * fcall is the primary packet structure
-  *
-  */
+/**
+ * struct p9_fcall - primary packet structure
+ * @size: prefixed length of the structure
+ * @id: protocol operating identifier of type &p9_msg_t
+ * @tag: transaction id of the request
+ * @sdata: payload
+ * @params: per-operation parameters
+ *
+ * &p9_fcall represents the structure for all 9P RPC
+ * transactions.  Requests are packaged into fcalls, and reponses
+ * must be extracted from them.
+ *
+ * See Also: http://plan9.bell-labs.com/magic/man2html/2/fcall
+ */
 
 struct p9_fcall {
 	u32 size;
@@ -416,4 +595,5 @@
 
 int p9_error_init(void);
 int p9_errstr2errno(char *, int);
+int p9_trans_fd_init(void);
 #endif /* NET_9P_H */
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index e52f93d..c936dd1 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -26,6 +26,23 @@
 #ifndef NET_9P_CLIENT_H
 #define NET_9P_CLIENT_H
 
+/**
+ * struct p9_client - per client instance state
+ * @lock: protect @fidlist
+ * @msize: maximum data size negotiated by protocol
+ * @dotu: extension flags negotiated by protocol
+ * @trans_mod: module API instantiated with this client
+ * @trans: tranport instance state and API
+ * @conn: connection state information used by trans_fd
+ * @fidpool: fid handle accounting for session
+ * @fidlist: List of active fid handles
+ *
+ * The client structure is used to keep track of various per-client
+ * state that has been instantiated.
+ *
+ * Bugs: duplicated data and potentially unnecessary elements.
+ */
+
 struct p9_client {
 	spinlock_t lock; /* protect client structure */
 	int msize;
@@ -38,6 +55,24 @@
 	struct list_head fidlist;
 };
 
+/**
+ * struct p9_fid - file system entity handle
+ * @clnt: back pointer to instantiating &p9_client
+ * @fid: numeric identifier for this handle
+ * @mode: current mode of this fid (enum?)
+ * @qid: the &p9_qid server identifier this handle points to
+ * @iounit: the server reported maximum transaction size for this file
+ * @uid: the numeric uid of the local user who owns this handle
+ * @aux: transport specific information (unused?)
+ * @rdir_fpos: tracks offset of file position when reading directory contents
+ * @rdir_pos: (unused?)
+ * @rdir_fcall: holds response of last directory read request
+ * @flist: per-client-instance fid tracking
+ * @dlist: per-dentry fid tracking
+ *
+ * TODO: This needs lots of explanation.
+ */
+
 struct p9_fid {
 	struct p9_client *clnt;
 	u32 fid;
diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h
index d2209ae..0db3a40 100644
--- a/include/net/9p/transport.h
+++ b/include/net/9p/transport.h
@@ -26,12 +26,40 @@
 #ifndef NET_9P_TRANSPORT_H
 #define NET_9P_TRANSPORT_H
 
+/**
+ * enum p9_trans_status - different states of underlying transports
+ * @Connected: transport is connected and healthy
+ * @Disconnected: transport has been disconnected
+ * @Hung: transport is connected by wedged
+ *
+ * This enumeration details the various states a transport
+ * instatiation can be in.
+ */
+
 enum p9_trans_status {
 	Connected,
 	Disconnected,
 	Hung,
 };
 
+/**
+ * struct p9_trans - per-transport state and API
+ * @status: transport &p9_trans_status
+ * @msize: negotiated maximum packet size (duplicate from client)
+ * @extended: negotiated protocol extensions (duplicate from client)
+ * @priv: transport private data
+ * @close: member function to disconnect and close the transport
+ * @rpc: member function to issue a request to the transport
+ *
+ * This is the basic API for a transport instance.  It is used as
+ * a handle by the client to issue requests.  This interface is currently
+ * in flux during reorganization.
+ *
+ * Bugs: there is lots of duplicated data here and its not clear that
+ * the member functions need to be per-instance versus per transport
+ * module.
+ */
+
 struct p9_trans {
 	enum p9_trans_status status;
 	int msize;
@@ -42,6 +70,21 @@
 							struct p9_fcall **rc);
 };
 
+/**
+ * struct p9_trans_module - transport module interface
+ * @list: used to maintain a list of currently available transports
+ * @name: the human-readable name of the transport
+ * @maxsize: transport provided maximum packet size
+ * @def: set if this transport should be considered the default
+ * @create: member function to create a new connection on this transport
+ *
+ * This is the basic API for a transport module which is registered by the
+ * transport module with the 9P core network module and used by the client
+ * to instantiate a new connection on a transport.
+ *
+ * Bugs: the transport module list isn't protected.
+ */
+
 struct p9_trans_module {
 	struct list_head list;
 	char *name;		/* name of transport */
@@ -53,5 +96,4 @@
 void v9fs_register_trans(struct p9_trans_module *m);
 struct p9_trans_module *v9fs_match_trans(const substring_t *name);
 struct p9_trans_module *v9fs_default_trans(void);
-
 #endif /* NET_9P_TRANSPORT_H */
diff --git a/include/net/ip.h b/include/net/ip.h
index 6d7bcd5..3b40bc2 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -210,7 +210,7 @@
 {
 	return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO ||
 		(inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT &&
-		 !(dst_metric(dst, RTAX_LOCK)&(1<<RTAX_MTU))));
+		 !(dst_metric_locked(dst, RTAX_MTU))));
 }
 
 extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);
diff --git a/include/net/irda/discovery.h b/include/net/irda/discovery.h
index e4efad1..0ce9339 100644
--- a/include/net/irda/discovery.h
+++ b/include/net/irda/discovery.h
@@ -57,9 +57,6 @@
 	__u8  byte[2];
 } __u16_host_order;
 
-/* Same purpose, different application */
-#define u16ho(array) (* ((__u16 *) array))
-
 /* Types of discovery */
 typedef enum {
 	DISCOVERY_LOG,		/* What's in our discovery log */
diff --git a/include/net/syncppp.h b/include/net/syncppp.h
index 877efa4..e43f407 100644
--- a/include/net/syncppp.h
+++ b/include/net/syncppp.h
@@ -59,7 +59,7 @@
 
 static inline struct sppp *sppp_of(struct net_device *dev) 
 {
-	struct ppp_device **ppp = dev->priv;
+	struct ppp_device **ppp = dev->ml_priv;
 	BUG_ON((*ppp)->dev != dev);
 	return &(*ppp)->sppp;
 }
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index d1350bc..2933d747 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -648,14 +648,46 @@
 extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
 				     struct sk_buff *skb, u8 proto);
 #else
-#define xfrm_audit_policy_add(x, r, a, se, s)	do { ; } while (0)
-#define xfrm_audit_policy_delete(x, r, a, se, s)	do { ; } while (0)
-#define xfrm_audit_state_add(x, r, a, se, s)	do { ; } while (0)
-#define xfrm_audit_state_delete(x, r, a, se, s)	do { ; } while (0)
-#define xfrm_audit_state_replay_overflow(x, s)	do { ; } while (0)
-#define xfrm_audit_state_notfound_simple(s, f)	do { ; } while (0)
-#define xfrm_audit_state_notfound(s, f, sp, sq)	do { ; } while (0)
-#define xfrm_audit_state_icvfail(x, s, p)	do { ; } while (0)
+
+static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
+				  u32 auid, u32 ses, u32 secid)
+{
+}
+
+static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
+				  u32 auid, u32 ses, u32 secid)
+{
+}
+
+static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
+				 u32 auid, u32 ses, u32 secid)
+{
+}
+
+static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
+				    u32 auid, u32 ses, u32 secid)
+{
+}
+
+static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
+					     struct sk_buff *skb)
+{
+}
+
+static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
+				      u16 family)
+{
+}
+
+static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
+				      __be32 net_spi, __be32 net_seq)
+{
+}
+
+static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
+				     struct sk_buff *skb, u8 proto)
+{
+}
 #endif /* CONFIG_AUDITSYSCALL */
 
 static inline void xfrm_pol_hold(struct xfrm_policy *policy)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index e6ea6f7..d3c8c03 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -238,7 +238,7 @@
 	struct snd_ctl_elem_info *uinfo);
 int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_info *uinfo);
-#define snd_soc_info_bool_ext		snd_ctl_boolean_mono
+#define snd_soc_info_bool_ext		snd_ctl_boolean_mono_info
 int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol);
 int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
diff --git a/init/Kconfig b/init/Kconfig
index f0e62e5..6135d07 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -316,9 +316,16 @@
 
 	  Say N if unsure.
 
+#
+# Architectures with an unreliable sched_clock() should select this:
+#
+config HAVE_UNSTABLE_SCHED_CLOCK
+	bool
+
 config GROUP_SCHED
 	bool "Group CPU scheduler"
-	default y
+	depends on EXPERIMENTAL
+	default n
 	help
 	  This feature lets CPU scheduler recognize task groups and control CPU
 	  bandwidth allocation to such task groups.
@@ -326,7 +333,7 @@
 config FAIR_GROUP_SCHED
 	bool "Group scheduling for SCHED_OTHER"
 	depends on GROUP_SCHED
-	default y
+	default GROUP_SCHED
 
 config RT_GROUP_SCHED
 	bool "Group scheduling for SCHED_RR/FIFO"
@@ -627,6 +634,14 @@
 	help
 	  Enable support for generating core dumps. Disabling saves about 4k.
 
+config PCSPKR_PLATFORM
+	bool "Enable PC-Speaker support" if EMBEDDED
+	depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+	default y
+	help
+          This option allows to disable the internal PC-Speaker
+          support, saving some memory.
+
 config COMPAT_BRK
 	bool "Disable heap randomization"
 	default y
@@ -830,9 +845,9 @@
 	depends on MODULES
 	default n
 	help
-	  This option allows loading of modules even if that would set the
-          'F' (forced) taint, due to lack of version info.  Which is
-	  usually a really bad idea.
+	  Allow loading of modules without version information (ie. modprobe
+	  --force).  Forced module loading sets the 'F' (forced) taint flag and
+	  is usually a really bad idea.
 
 config MODULE_UNLOAD
 	bool "Module unloading"
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 3885e70..660c1e5 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -76,6 +76,7 @@
 	char s[32];
 	char *p;
 	dev_t res = 0;
+	int part;
 
 	if (strncmp(name, "/dev/", 5) != 0) {
 		unsigned maj, min;
@@ -106,7 +107,31 @@
 	for (p = s; *p; p++)
 		if (*p == '/')
 			*p = '!';
-	res = blk_lookup_devt(s);
+	res = blk_lookup_devt(s, 0);
+	if (res)
+		goto done;
+
+	/*
+	 * try non-existant, but valid partition, which may only exist
+	 * after revalidating the disk, like partitioned md devices
+	 */
+	while (p > s && isdigit(p[-1]))
+		p--;
+	if (p == s || !*p || *p == '0')
+		goto fail;
+
+	/* try disk name without <part number> */
+	part = simple_strtoul(p, NULL, 10);
+	*p = '\0';
+	res = blk_lookup_devt(s, part);
+	if (res)
+		goto done;
+
+	/* try disk name without p<part number> */
+	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
+		goto fail;
+	p[-1] = '\0';
+	res = blk_lookup_devt(s, part);
 	if (res)
 		goto done;
 
diff --git a/init/main.c b/init/main.c
index a87d4ca5..f406fef 100644
--- a/init/main.c
+++ b/init/main.c
@@ -602,6 +602,7 @@
 	softirq_init();
 	timekeeping_init();
 	time_init();
+	sched_clock_init();
 	profile_init();
 	if (!irqs_disabled())
 		printk("start_kernel(): bug: interrupts were enabled early\n");
@@ -701,7 +702,6 @@
 
 	for (call = __initcall_start; call < __initcall_end; call++) {
 		ktime_t t0, t1, delta;
-		char *msg = NULL;
 		char msgbuf[40];
 		int result;
 
@@ -723,22 +723,23 @@
 				(unsigned long long) delta.tv64 >> 20);
 		}
 
-		if (result && result != -ENODEV && initcall_debug) {
-			sprintf(msgbuf, "error code %d", result);
-			msg = msgbuf;
-		}
+		msgbuf[0] = 0;
+
+		if (result && result != -ENODEV && initcall_debug)
+			sprintf(msgbuf, "error code %d ", result);
+
 		if (preempt_count() != count) {
-			msg = "preemption imbalance";
+			strncat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
 			preempt_count() = count;
 		}
 		if (irqs_disabled()) {
-			msg = "disabled interrupts";
+			strncat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
 			local_irq_enable();
 		}
-		if (msg) {
+		if (msgbuf[0]) {
 			print_fn_descriptor_symbol(KERN_WARNING "initcall %s()",
 					(unsigned long) *call);
-			printk(" returned with %s\n", msg);
+			printk(" returned with %s\n", msgbuf);
 		}
 	}
 
diff --git a/kernel/Makefile b/kernel/Makefile
index 188c432..1c9938a 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,7 +9,7 @@
 	    rcupdate.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
 	    hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
-	    notifier.o ksysfs.o pm_qos_params.o
+	    notifier.o ksysfs.o pm_qos_params.o sched_clock.o
 
 obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 8da627d..86ea9e3 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1031,11 +1031,9 @@
 	return task_cs(current) == cpuset_being_rebound;
 }
 
-static int update_relax_domain_level(struct cpuset *cs, char *buf)
+static int update_relax_domain_level(struct cpuset *cs, s64 val)
 {
-	int val = simple_strtol(buf, NULL, 10);
-
-	if (val < 0)
+	if ((int)val < 0)
 		val = -1;
 
 	if (val != cs->relax_domain_level) {
@@ -1280,9 +1278,6 @@
 	case FILE_MEMLIST:
 		retval = update_nodemask(cs, buffer);
 		break;
-	case FILE_SCHED_RELAX_DOMAIN_LEVEL:
-		retval = update_relax_domain_level(cs, buffer);
-		break;
 	default:
 		retval = -EINVAL;
 		goto out2;
@@ -1348,6 +1343,30 @@
 	return retval;
 }
 
+static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val)
+{
+	int retval = 0;
+	struct cpuset *cs = cgroup_cs(cgrp);
+	cpuset_filetype_t type = cft->private;
+
+	cgroup_lock();
+
+	if (cgroup_is_removed(cgrp)) {
+		cgroup_unlock();
+		return -ENODEV;
+	}
+	switch (type) {
+	case FILE_SCHED_RELAX_DOMAIN_LEVEL:
+		retval = update_relax_domain_level(cs, val);
+		break;
+	default:
+		retval = -EINVAL;
+		break;
+	}
+	cgroup_unlock();
+	return retval;
+}
+
 /*
  * These ascii lists should be read in a single call, by using a user
  * buffer large enough to hold the entire map.  If read in smaller
@@ -1406,9 +1425,6 @@
 	case FILE_MEMLIST:
 		s += cpuset_sprintf_memlist(s, cs);
 		break;
-	case FILE_SCHED_RELAX_DOMAIN_LEVEL:
-		s += sprintf(s, "%d", cs->relax_domain_level);
-		break;
 	default:
 		retval = -EINVAL;
 		goto out;
@@ -1449,6 +1465,18 @@
 	}
 }
 
+static s64 cpuset_read_s64(struct cgroup *cont, struct cftype *cft)
+{
+	struct cpuset *cs = cgroup_cs(cont);
+	cpuset_filetype_t type = cft->private;
+	switch (type) {
+	case FILE_SCHED_RELAX_DOMAIN_LEVEL:
+		return cs->relax_domain_level;
+	default:
+		BUG();
+	}
+}
+
 
 /*
  * for the common functions, 'private' gives the type of file
@@ -1499,8 +1527,8 @@
 
 	{
 		.name = "sched_relax_domain_level",
-		.read_u64 = cpuset_read_u64,
-		.write_u64 = cpuset_write_u64,
+		.read_s64 = cpuset_read_s64,
+		.write_s64 = cpuset_write_s64,
 		.private = FILE_SCHED_RELAX_DOMAIN_LEVEL,
 	},
 
diff --git a/kernel/futex.c b/kernel/futex.c
index 98092c9..449def8 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -104,10 +104,6 @@
 	/* Key which the futex is hashed on: */
 	union futex_key key;
 
-	/* For fd, sigio sent using these: */
-	int fd;
-	struct file *filp;
-
 	/* Optional priority inheritance state: */
 	struct futex_pi_state *pi_state;
 	struct task_struct *task;
@@ -126,9 +122,6 @@
 
 static struct futex_hash_bucket futex_queues[1<<FUTEX_HASHBITS];
 
-/* Futex-fs vfsmount entry: */
-static struct vfsmount *futex_mnt;
-
 /*
  * Take mm->mmap_sem, when futex is shared
  */
@@ -610,8 +603,6 @@
 static void wake_futex(struct futex_q *q)
 {
 	plist_del(&q->list, &q->list.plist);
-	if (q->filp)
-		send_sigio(&q->filp->f_owner, q->fd, POLL_IN);
 	/*
 	 * The lock in wake_up_all() is a crucial memory barrier after the
 	 * plist_del() and also before assigning to q->lock_ptr.
@@ -988,14 +979,10 @@
 }
 
 /* The key must be already stored in q->key. */
-static inline struct futex_hash_bucket *
-queue_lock(struct futex_q *q, int fd, struct file *filp)
+static inline struct futex_hash_bucket *queue_lock(struct futex_q *q)
 {
 	struct futex_hash_bucket *hb;
 
-	q->fd = fd;
-	q->filp = filp;
-
 	init_waitqueue_head(&q->waiters);
 
 	get_futex_key_refs(&q->key);
@@ -1006,7 +993,7 @@
 	return hb;
 }
 
-static inline void __queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
+static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
 {
 	int prio;
 
@@ -1041,15 +1028,6 @@
  * exactly once.  They are called with the hashed spinlock held.
  */
 
-/* The key must be already stored in q->key. */
-static void queue_me(struct futex_q *q, int fd, struct file *filp)
-{
-	struct futex_hash_bucket *hb;
-
-	hb = queue_lock(q, fd, filp);
-	__queue_me(q, hb);
-}
-
 /* Return 1 if we were still queued (ie. 0 means we were woken) */
 static int unqueue_me(struct futex_q *q)
 {
@@ -1194,7 +1172,7 @@
 	if (unlikely(ret != 0))
 		goto out_release_sem;
 
-	hb = queue_lock(&q, -1, NULL);
+	hb = queue_lock(&q);
 
 	/*
 	 * Access the page AFTER the futex is queued.
@@ -1238,7 +1216,7 @@
 		goto out_unlock_release_sem;
 
 	/* Only actually queue if *uaddr contained val.  */
-	__queue_me(&q, hb);
+	queue_me(&q, hb);
 
 	/*
 	 * Now the futex is queued and we have checked the data, we
@@ -1386,7 +1364,7 @@
 		goto out_release_sem;
 
  retry_unlocked:
-	hb = queue_lock(&q, -1, NULL);
+	hb = queue_lock(&q);
 
  retry_locked:
 	ret = lock_taken = 0;
@@ -1499,7 +1477,7 @@
 	/*
 	 * Only actually queue now that the atomic ops are done:
 	 */
-	__queue_me(&q, hb);
+	queue_me(&q, hb);
 
 	/*
 	 * Now the futex is queued and we have checked the data, we
@@ -1746,121 +1724,6 @@
 	return ret;
 }
 
-static int futex_close(struct inode *inode, struct file *filp)
-{
-	struct futex_q *q = filp->private_data;
-
-	unqueue_me(q);
-	kfree(q);
-
-	return 0;
-}
-
-/* This is one-shot: once it's gone off you need a new fd */
-static unsigned int futex_poll(struct file *filp,
-			       struct poll_table_struct *wait)
-{
-	struct futex_q *q = filp->private_data;
-	int ret = 0;
-
-	poll_wait(filp, &q->waiters, wait);
-
-	/*
-	 * plist_node_empty() is safe here without any lock.
-	 * q->lock_ptr != 0 is not safe, because of ordering against wakeup.
-	 */
-	if (plist_node_empty(&q->list))
-		ret = POLLIN | POLLRDNORM;
-
-	return ret;
-}
-
-static const struct file_operations futex_fops = {
-	.release	= futex_close,
-	.poll		= futex_poll,
-};
-
-/*
- * Signal allows caller to avoid the race which would occur if they
- * set the sigio stuff up afterwards.
- */
-static int futex_fd(u32 __user *uaddr, int signal)
-{
-	struct futex_q *q;
-	struct file *filp;
-	int ret, err;
-	struct rw_semaphore *fshared;
-	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))
-		goto out;
-
-	ret = get_unused_fd();
-	if (ret < 0)
-		goto out;
-	filp = get_empty_filp();
-	if (!filp) {
-		put_unused_fd(ret);
-		ret = -ENFILE;
-		goto out;
-	}
-	filp->f_op = &futex_fops;
-	filp->f_path.mnt = mntget(futex_mnt);
-	filp->f_path.dentry = dget(futex_mnt->mnt_root);
-	filp->f_mapping = filp->f_path.dentry->d_inode->i_mapping;
-
-	if (signal) {
-		err = __f_setown(filp, task_pid(current), PIDTYPE_PID, 1);
-		if (err < 0) {
-			goto error;
-		}
-		filp->f_owner.signum = signal;
-	}
-
-	q = kmalloc(sizeof(*q), GFP_KERNEL);
-	if (!q) {
-		err = -ENOMEM;
-		goto error;
-	}
-	q->pi_state = NULL;
-
-	fshared = &current->mm->mmap_sem;
-	down_read(fshared);
-	err = get_futex_key(uaddr, fshared, &q->key);
-
-	if (unlikely(err != 0)) {
-		up_read(fshared);
-		kfree(q);
-		goto error;
-	}
-
-	/*
-	 * queue_me() must be called before releasing mmap_sem, because
-	 * key->shared.inode needs to be referenced while holding it.
-	 */
-	filp->private_data = q;
-
-	queue_me(q, ret, filp);
-	up_read(fshared);
-
-	/* Now we map fd to filp, so userspace can access it */
-	fd_install(ret, filp);
-out:
-	return ret;
-error:
-	put_unused_fd(ret);
-	put_filp(filp);
-	ret = err;
-	goto out;
-}
-
 /*
  * Support for robust futexes: the kernel cleans up held futexes at
  * thread exit time.
@@ -2092,10 +1955,6 @@
 	case FUTEX_WAKE_BITSET:
 		ret = futex_wake(uaddr, fshared, val, val3);
 		break;
-	case FUTEX_FD:
-		/* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */
-		ret = futex_fd(uaddr, val);
-		break;
 	case FUTEX_REQUEUE:
 		ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, NULL);
 		break;
@@ -2156,19 +2015,6 @@
 	return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
 }
 
-static int futexfs_get_sb(struct file_system_type *fs_type,
-			  int flags, const char *dev_name, void *data,
-			  struct vfsmount *mnt)
-{
-	return get_sb_pseudo(fs_type, "futex", NULL, FUTEXFS_SUPER_MAGIC, mnt);
-}
-
-static struct file_system_type futex_fs_type = {
-	.name		= "futexfs",
-	.get_sb		= futexfs_get_sb,
-	.kill_sb	= kill_anon_super,
-};
-
 static int __init futex_init(void)
 {
 	u32 curval;
@@ -2193,16 +2039,6 @@
 		spin_lock_init(&futex_queues[i].lock);
 	}
 
-	i = register_filesystem(&futex_fs_type);
-	if (i)
-		return i;
-
-	futex_mnt = kern_mount(&futex_fs_type);
-	if (IS_ERR(futex_mnt)) {
-		unregister_filesystem(&futex_fs_type);
-		return PTR_ERR(futex_mnt);
-	}
-
 	return 0;
 }
 __initcall(futex_init);
diff --git a/kernel/kgdb.c b/kernel/kgdb.c
index 1bd0ec1..14787de 100644
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -61,7 +61,7 @@
 	int			err_code;
 	int			cpu;
 	int			pass_exception;
-	long			threadid;
+	unsigned long		threadid;
 	long			kgdb_usethreadid;
 	struct pt_regs		*linux_regs;
 };
@@ -146,7 +146,7 @@
  * the other CPUs might interfere with your debugging context, so
  * use this with care:
  */
-int				kgdb_do_roundup = 1;
+static int kgdb_do_roundup = 1;
 
 static int __init opt_nokgdbroundup(char *str)
 {
@@ -346,14 +346,6 @@
 	}
 }
 
-static char *pack_hex_byte(char *pkt, u8 byte)
-{
-	*pkt++ = hexchars[byte >> 4];
-	*pkt++ = hexchars[byte & 0xf];
-
-	return pkt;
-}
-
 /*
  * Convert the memory pointed to by mem into hex, placing result in buf.
  * Return a pointer to the last char put in buf (null). May return an error.
@@ -438,7 +430,7 @@
  * While we find nice hex chars, build a long_val.
  * Return number of chars processed.
  */
-int kgdb_hex2long(char **ptr, long *long_val)
+int kgdb_hex2long(char **ptr, unsigned long *long_val)
 {
 	int hex_val;
 	int num = 0;
@@ -709,7 +701,7 @@
 	return 0;
 }
 
-int remove_all_break(void)
+static int remove_all_break(void)
 {
 	unsigned long addr;
 	int error;
diff --git a/kernel/module.c b/kernel/module.c
index 8e4528c..f5e9491 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -917,6 +917,10 @@
 	if (!crc)
 		return 1;
 
+	/* No versions at all?  modprobe --force does this. */
+	if (versindex == 0)
+		return try_to_force_load(mod, symname) == 0;
+
 	versions = (void *) sechdrs[versindex].sh_addr;
 	num_versions = sechdrs[versindex].sh_size
 		/ sizeof(struct modversion_info);
@@ -932,8 +936,9 @@
 		goto bad_version;
 	}
 
-	if (!try_to_force_load(mod, symname))
-		return 1;
+	printk(KERN_WARNING "%s: no symbol version for %s\n",
+	       mod->name, symname);
+	return 0;
 
 bad_version:
 	printk("%s: disagrees about version of symbol %s\n",
@@ -952,11 +957,14 @@
 	return check_version(sechdrs, versindex, "struct_module", mod, crc);
 }
 
-/* First part is kernel version, which we ignore. */
-static inline int same_magic(const char *amagic, const char *bmagic)
+/* First part is kernel version, which we ignore if module has crcs. */
+static inline int same_magic(const char *amagic, const char *bmagic,
+			     bool has_crcs)
 {
-	amagic += strcspn(amagic, " ");
-	bmagic += strcspn(bmagic, " ");
+	if (has_crcs) {
+		amagic += strcspn(amagic, " ");
+		bmagic += strcspn(bmagic, " ");
+	}
 	return strcmp(amagic, bmagic) == 0;
 }
 #else
@@ -976,7 +984,8 @@
 	return 1;
 }
 
-static inline int same_magic(const char *amagic, const char *bmagic)
+static inline int same_magic(const char *amagic, const char *bmagic,
+			     bool has_crcs)
 {
 	return strcmp(amagic, bmagic) == 0;
 }
@@ -1869,7 +1878,7 @@
 		err = try_to_force_load(mod, "magic");
 		if (err)
 			goto free_hdr;
-	} else if (!same_magic(modmagic, vermagic)) {
+	} else if (!same_magic(modmagic, vermagic, versindex)) {
 		printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
 		       mod->name, modmagic, vermagic);
 		err = -ENOEXEC;
diff --git a/kernel/relay.c b/kernel/relay.c
index 7de644c..bc24dcd 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -1191,7 +1191,7 @@
 	ret = 0;
 	spliced = 0;
 
-	while (len && !spliced) {
+	while (len) {
 		ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
 		if (ret < 0)
 			break;
diff --git a/kernel/sched.c b/kernel/sched.c
index 34bcc5b..cfa222a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -75,16 +75,6 @@
 #include <asm/irq_regs.h>
 
 /*
- * Scheduler clock - returns current time in nanosec units.
- * This is default implementation.
- * Architectures and sub-architectures can override this.
- */
-unsigned long long __attribute__((weak)) sched_clock(void)
-{
-	return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
-}
-
-/*
  * Convert user-nice values [ -20 ... 0 ... 19 ]
  * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
  * and back.
@@ -242,6 +232,12 @@
 }
 #endif
 
+/*
+ * sched_domains_mutex serializes calls to arch_init_sched_domains,
+ * detach_destroy_domains and partition_sched_domains.
+ */
+static DEFINE_MUTEX(sched_domains_mutex);
+
 #ifdef CONFIG_GROUP_SCHED
 
 #include <linux/cgroup.h>
@@ -308,9 +304,6 @@
  */
 static DEFINE_SPINLOCK(task_group_lock);
 
-/* doms_cur_mutex serializes access to doms_cur[] array */
-static DEFINE_MUTEX(doms_cur_mutex);
-
 #ifdef CONFIG_FAIR_GROUP_SCHED
 #ifdef CONFIG_USER_SCHED
 # define INIT_TASK_GROUP_LOAD	(2*NICE_0_LOAD)
@@ -318,7 +311,13 @@
 # define INIT_TASK_GROUP_LOAD	NICE_0_LOAD
 #endif
 
+/*
+ * A weight of 0, 1 or ULONG_MAX can cause arithmetics problems.
+ * (The default weight is 1024 - so there's no practical
+ *  limitation from this.)
+ */
 #define MIN_SHARES	2
+#define MAX_SHARES	(ULONG_MAX - 1)
 
 static int init_task_group_load = INIT_TASK_GROUP_LOAD;
 #endif
@@ -358,21 +357,9 @@
 #endif
 }
 
-static inline void lock_doms_cur(void)
-{
-	mutex_lock(&doms_cur_mutex);
-}
-
-static inline void unlock_doms_cur(void)
-{
-	mutex_unlock(&doms_cur_mutex);
-}
-
 #else
 
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { }
-static inline void lock_doms_cur(void) { }
-static inline void unlock_doms_cur(void) { }
 
 #endif	/* CONFIG_GROUP_SCHED */
 
@@ -560,13 +547,7 @@
 	unsigned long next_balance;
 	struct mm_struct *prev_mm;
 
-	u64 clock, prev_clock_raw;
-	s64 clock_max_delta;
-
-	unsigned int clock_warps, clock_overflows, clock_underflows;
-	u64 idle_clock;
-	unsigned int clock_deep_idle_events;
-	u64 tick_timestamp;
+	u64 clock;
 
 	atomic_t nr_iowait;
 
@@ -631,82 +612,6 @@
 #endif
 }
 
-#ifdef CONFIG_NO_HZ
-static inline bool nohz_on(int cpu)
-{
-	return tick_get_tick_sched(cpu)->nohz_mode != NOHZ_MODE_INACTIVE;
-}
-
-static inline u64 max_skipped_ticks(struct rq *rq)
-{
-	return nohz_on(cpu_of(rq)) ? jiffies - rq->last_tick_seen + 2 : 1;
-}
-
-static inline void update_last_tick_seen(struct rq *rq)
-{
-	rq->last_tick_seen = jiffies;
-}
-#else
-static inline u64 max_skipped_ticks(struct rq *rq)
-{
-	return 1;
-}
-
-static inline void update_last_tick_seen(struct rq *rq)
-{
-}
-#endif
-
-/*
- * Update the per-runqueue clock, as finegrained as the platform can give
- * us, but without assuming monotonicity, etc.:
- */
-static void __update_rq_clock(struct rq *rq)
-{
-	u64 prev_raw = rq->prev_clock_raw;
-	u64 now = sched_clock();
-	s64 delta = now - prev_raw;
-	u64 clock = rq->clock;
-
-#ifdef CONFIG_SCHED_DEBUG
-	WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
-#endif
-	/*
-	 * Protect against sched_clock() occasionally going backwards:
-	 */
-	if (unlikely(delta < 0)) {
-		clock++;
-		rq->clock_warps++;
-	} else {
-		/*
-		 * Catch too large forward jumps too:
-		 */
-		u64 max_jump = max_skipped_ticks(rq) * TICK_NSEC;
-		u64 max_time = rq->tick_timestamp + max_jump;
-
-		if (unlikely(clock + delta > max_time)) {
-			if (clock < max_time)
-				clock = max_time;
-			else
-				clock++;
-			rq->clock_overflows++;
-		} else {
-			if (unlikely(delta > rq->clock_max_delta))
-				rq->clock_max_delta = delta;
-			clock += delta;
-		}
-	}
-
-	rq->prev_clock_raw = now;
-	rq->clock = clock;
-}
-
-static void update_rq_clock(struct rq *rq)
-{
-	if (likely(smp_processor_id() == cpu_of(rq)))
-		__update_rq_clock(rq);
-}
-
 /*
  * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
  * See detach_destroy_domains: synchronize_sched for details.
@@ -722,6 +627,11 @@
 #define task_rq(p)		cpu_rq(task_cpu(p))
 #define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
 
+static inline void update_rq_clock(struct rq *rq)
+{
+	rq->clock = sched_clock_cpu(cpu_of(rq));
+}
+
 /*
  * Tunables that become constants when CONFIG_SCHED_DEBUG is off:
  */
@@ -757,14 +667,14 @@
 #define SCHED_FEAT(name, enabled)	\
 	#name ,
 
-__read_mostly char *sched_feat_names[] = {
+static __read_mostly char *sched_feat_names[] = {
 #include "sched_features.h"
 	NULL
 };
 
 #undef SCHED_FEAT
 
-int sched_feat_open(struct inode *inode, struct file *filp)
+static int sched_feat_open(struct inode *inode, struct file *filp)
 {
 	filp->private_data = inode->i_private;
 	return 0;
@@ -899,7 +809,7 @@
 	return (u64)sysctl_sched_rt_runtime * NSEC_PER_USEC;
 }
 
-static const unsigned long long time_sync_thresh = 100000;
+unsigned long long time_sync_thresh = 100000;
 
 static DEFINE_PER_CPU(unsigned long long, time_offset);
 static DEFINE_PER_CPU(unsigned long long, prev_cpu_time);
@@ -913,11 +823,14 @@
 static DEFINE_SPINLOCK(time_sync_lock);
 static unsigned long long prev_global_time;
 
-static unsigned long long __sync_cpu_clock(cycles_t time, int cpu)
+static unsigned long long __sync_cpu_clock(unsigned long long time, int cpu)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&time_sync_lock, flags);
+	/*
+	 * We want this inlined, to not get tracer function calls
+	 * in this critical section:
+	 */
+	spin_acquire(&time_sync_lock.dep_map, 0, 0, _THIS_IP_);
+	__raw_spin_lock(&time_sync_lock.raw_lock);
 
 	if (time < prev_global_time) {
 		per_cpu(time_offset, cpu) += prev_global_time - time;
@@ -926,7 +839,8 @@
 		prev_global_time = time;
 	}
 
-	spin_unlock_irqrestore(&time_sync_lock, flags);
+	__raw_spin_unlock(&time_sync_lock.raw_lock);
+	spin_release(&time_sync_lock.dep_map, 1, _THIS_IP_);
 
 	return time;
 }
@@ -934,8 +848,6 @@
 static unsigned long long __cpu_clock(int cpu)
 {
 	unsigned long long now;
-	unsigned long flags;
-	struct rq *rq;
 
 	/*
 	 * Only call sched_clock() if the scheduler has already been
@@ -944,11 +856,7 @@
 	if (unlikely(!scheduler_running))
 		return 0;
 
-	local_irq_save(flags);
-	rq = cpu_rq(cpu);
-	update_rq_clock(rq);
-	now = rq->clock;
-	local_irq_restore(flags);
+	now = sched_clock_cpu(cpu);
 
 	return now;
 }
@@ -960,13 +868,18 @@
 unsigned long long cpu_clock(int cpu)
 {
 	unsigned long long prev_cpu_time, time, delta_time;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	prev_cpu_time = per_cpu(prev_cpu_time, cpu);
 	time = __cpu_clock(cpu) + per_cpu(time_offset, cpu);
 	delta_time = time-prev_cpu_time;
 
-	if (unlikely(delta_time > time_sync_thresh))
+	if (unlikely(delta_time > time_sync_thresh)) {
 		time = __sync_cpu_clock(time, cpu);
+		per_cpu(prev_cpu_time, cpu) = time;
+	}
+	local_irq_restore(flags);
 
 	return time;
 }
@@ -1117,43 +1030,6 @@
 	return rq;
 }
 
-/*
- * We are going deep-idle (irqs are disabled):
- */
-void sched_clock_idle_sleep_event(void)
-{
-	struct rq *rq = cpu_rq(smp_processor_id());
-
-	spin_lock(&rq->lock);
-	__update_rq_clock(rq);
-	spin_unlock(&rq->lock);
-	rq->clock_deep_idle_events++;
-}
-EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
-
-/*
- * We just idled delta nanoseconds (called with irqs disabled):
- */
-void sched_clock_idle_wakeup_event(u64 delta_ns)
-{
-	struct rq *rq = cpu_rq(smp_processor_id());
-	u64 now = sched_clock();
-
-	rq->idle_clock += delta_ns;
-	/*
-	 * Override the previous timestamp and ignore all
-	 * sched_clock() deltas that occured while we idled,
-	 * and use the PM-provided delta_ns to advance the
-	 * rq clock:
-	 */
-	spin_lock(&rq->lock);
-	rq->prev_clock_raw = now;
-	rq->clock += delta_ns;
-	spin_unlock(&rq->lock);
-	touch_softlockup_watchdog();
-}
-EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
-
 static void __resched_task(struct task_struct *p, int tif_bit);
 
 static inline void resched_task(struct task_struct *p)
@@ -1189,6 +1065,7 @@
 enum {
 	HRTICK_SET,		/* re-programm hrtick_timer */
 	HRTICK_RESET,		/* not a new slice */
+	HRTICK_BLOCK,		/* stop hrtick operations */
 };
 
 /*
@@ -1200,6 +1077,8 @@
 {
 	if (!sched_feat(HRTICK))
 		return 0;
+	if (unlikely(test_bit(HRTICK_BLOCK, &rq->hrtick_flags)))
+		return 0;
 	return hrtimer_is_hres_active(&rq->hrtick_timer);
 }
 
@@ -1275,14 +1154,70 @@
 	WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
 
 	spin_lock(&rq->lock);
-	__update_rq_clock(rq);
+	update_rq_clock(rq);
 	rq->curr->sched_class->task_tick(rq, rq->curr, 1);
 	spin_unlock(&rq->lock);
 
 	return HRTIMER_NORESTART;
 }
 
-static inline void init_rq_hrtick(struct rq *rq)
+static void hotplug_hrtick_disable(int cpu)
+{
+	struct rq *rq = cpu_rq(cpu);
+	unsigned long flags;
+
+	spin_lock_irqsave(&rq->lock, flags);
+	rq->hrtick_flags = 0;
+	__set_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+	spin_unlock_irqrestore(&rq->lock, flags);
+
+	hrtick_clear(rq);
+}
+
+static void hotplug_hrtick_enable(int cpu)
+{
+	struct rq *rq = cpu_rq(cpu);
+	unsigned long flags;
+
+	spin_lock_irqsave(&rq->lock, flags);
+	__clear_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+	spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static int
+hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+	int cpu = (int)(long)hcpu;
+
+	switch (action) {
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
+	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
+	case CPU_DEAD:
+	case CPU_DEAD_FROZEN:
+		hotplug_hrtick_disable(cpu);
+		return NOTIFY_OK;
+
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+	case CPU_DOWN_FAILED:
+	case CPU_DOWN_FAILED_FROZEN:
+	case CPU_ONLINE:
+	case CPU_ONLINE_FROZEN:
+		hotplug_hrtick_enable(cpu);
+		return NOTIFY_OK;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static void init_hrtick(void)
+{
+	hotcpu_notifier(hotplug_hrtick, 0);
+}
+
+static void init_rq_hrtick(struct rq *rq)
 {
 	rq->hrtick_flags = 0;
 	hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -1319,6 +1254,10 @@
 void hrtick_resched(void)
 {
 }
+
+static inline void init_hrtick(void)
+{
+}
 #endif
 
 /*
@@ -1438,8 +1377,8 @@
 {
 	u64 tmp;
 
-	if (unlikely(!lw->inv_weight))
-		lw->inv_weight = (WMULT_CONST-lw->weight/2) / (lw->weight+1);
+	if (!lw->inv_weight)
+		lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1);
 
 	tmp = (u64)delta_exec * weight;
 	/*
@@ -1748,6 +1687,8 @@
 
 	if (shares < MIN_SHARES)
 		shares = MIN_SHARES;
+	else if (shares > MAX_SHARES)
+		shares = MAX_SHARES;
 
 	__set_se_shares(tg->se[tcpu], shares);
 }
@@ -4339,8 +4280,10 @@
 	struct rq *rq = this_rq();
 	cputime64_t tmp;
 
-	if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0))
-		return account_guest_time(p, cputime);
+	if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
+		account_guest_time(p, cputime);
+		return;
+	}
 
 	p->stime = cputime_add(p->stime, cputime);
 
@@ -4404,19 +4347,11 @@
 	int cpu = smp_processor_id();
 	struct rq *rq = cpu_rq(cpu);
 	struct task_struct *curr = rq->curr;
-	u64 next_tick = rq->tick_timestamp + TICK_NSEC;
+
+	sched_clock_tick();
 
 	spin_lock(&rq->lock);
-	__update_rq_clock(rq);
-	/*
-	 * Let rq->clock advance by at least TICK_NSEC:
-	 */
-	if (unlikely(rq->clock < next_tick)) {
-		rq->clock = next_tick;
-		rq->clock_underflows++;
-	}
-	rq->tick_timestamp = rq->clock;
-	update_last_tick_seen(rq);
+	update_rq_clock(rq);
 	update_cpu_load(rq);
 	curr->sched_class->task_tick(rq, curr, 0);
 	spin_unlock(&rq->lock);
@@ -4570,7 +4505,7 @@
 	 * Do the rq-clock update outside the rq lock:
 	 */
 	local_irq_disable();
-	__update_rq_clock(rq);
+	update_rq_clock(rq);
 	spin_lock(&rq->lock);
 	clear_tsk_need_resched(prev);
 
@@ -4595,9 +4530,9 @@
 	prev->sched_class->put_prev_task(rq, prev);
 	next = pick_next_task(rq, prev);
 
-	sched_info_switch(prev, next);
-
 	if (likely(prev != next)) {
+		sched_info_switch(prev, next);
+
 		rq->nr_switches++;
 		rq->curr = next;
 		++*switch_count;
@@ -4632,8 +4567,6 @@
 asmlinkage void __sched preempt_schedule(void)
 {
 	struct thread_info *ti = current_thread_info();
-	struct task_struct *task = current;
-	int saved_lock_depth;
 
 	/*
 	 * If there is a non-zero preempt_count or interrupts are disabled,
@@ -4644,16 +4577,7 @@
 
 	do {
 		add_preempt_count(PREEMPT_ACTIVE);
-
-		/*
-		 * We keep the big kernel semaphore locked, but we
-		 * clear ->lock_depth so that schedule() doesnt
-		 * auto-release the semaphore:
-		 */
-		saved_lock_depth = task->lock_depth;
-		task->lock_depth = -1;
 		schedule();
-		task->lock_depth = saved_lock_depth;
 		sub_preempt_count(PREEMPT_ACTIVE);
 
 		/*
@@ -4674,26 +4598,15 @@
 asmlinkage void __sched preempt_schedule_irq(void)
 {
 	struct thread_info *ti = current_thread_info();
-	struct task_struct *task = current;
-	int saved_lock_depth;
 
 	/* Catch callers which need to be fixed */
 	BUG_ON(ti->preempt_count || !irqs_disabled());
 
 	do {
 		add_preempt_count(PREEMPT_ACTIVE);
-
-		/*
-		 * We keep the big kernel semaphore locked, but we
-		 * clear ->lock_depth so that schedule() doesnt
-		 * auto-release the semaphore:
-		 */
-		saved_lock_depth = task->lock_depth;
-		task->lock_depth = -1;
 		local_irq_enable();
 		schedule();
 		local_irq_disable();
-		task->lock_depth = saved_lock_depth;
 		sub_preempt_count(PREEMPT_ACTIVE);
 
 		/*
@@ -5612,7 +5525,6 @@
 	} while (need_resched());
 }
 
-#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY)
 int __sched _cond_resched(void)
 {
 	if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) &&
@@ -5623,7 +5535,6 @@
 	return 0;
 }
 EXPORT_SYMBOL(_cond_resched);
-#endif
 
 /*
  * cond_resched_lock() - if a reschedule is pending, drop the given lock,
@@ -5918,8 +5829,11 @@
 	spin_unlock_irqrestore(&rq->lock, flags);
 
 	/* Set the preempt count _outside_ the spinlocks! */
+#if defined(CONFIG_PREEMPT)
+	task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
+#else
 	task_thread_info(idle)->preempt_count = 0;
-
+#endif
 	/*
 	 * The idle tasks have their own, simple scheduling class:
 	 */
@@ -7755,7 +7669,7 @@
 {
 	int i, j;
 
-	lock_doms_cur();
+	mutex_lock(&sched_domains_mutex);
 
 	/* always unregister in case we don't destroy any domains */
 	unregister_sched_domain_sysctl();
@@ -7804,7 +7718,7 @@
 
 	register_sched_domain_sysctl();
 
-	unlock_doms_cur();
+	mutex_unlock(&sched_domains_mutex);
 }
 
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
@@ -7813,8 +7727,10 @@
 	int err;
 
 	get_online_cpus();
+	mutex_lock(&sched_domains_mutex);
 	detach_destroy_domains(&cpu_online_map);
 	err = arch_init_sched_domains(&cpu_online_map);
+	mutex_unlock(&sched_domains_mutex);
 	put_online_cpus();
 
 	return err;
@@ -7932,13 +7848,16 @@
 	BUG_ON(sched_group_nodes_bycpu == NULL);
 #endif
 	get_online_cpus();
+	mutex_lock(&sched_domains_mutex);
 	arch_init_sched_domains(&cpu_online_map);
 	cpus_andnot(non_isolated_cpus, cpu_possible_map, cpu_isolated_map);
 	if (cpus_empty(non_isolated_cpus))
 		cpu_set(smp_processor_id(), non_isolated_cpus);
+	mutex_unlock(&sched_domains_mutex);
 	put_online_cpus();
 	/* XXX: Theoretical race here - CPU may be hotplugged now */
 	hotcpu_notifier(update_sched_domains, 0);
+	init_hrtick();
 
 	/* Move init over to a non-isolated CPU */
 	if (set_cpus_allowed_ptr(current, &non_isolated_cpus) < 0)
@@ -8025,7 +7944,7 @@
 
 	se->my_q = cfs_rq;
 	se->load.weight = tg->shares;
-	se->load.inv_weight = div64_u64(1ULL<<32, se->load.weight);
+	se->load.inv_weight = 0;
 	se->parent = parent;
 }
 #endif
@@ -8149,8 +8068,6 @@
 		spin_lock_init(&rq->lock);
 		lockdep_set_class(&rq->lock, &rq->rq_lock_key);
 		rq->nr_running = 0;
-		rq->clock = 1;
-		update_last_tick_seen(rq);
 		init_cfs_rq(&rq->cfs, rq);
 		init_rt_rq(&rq->rt, rq);
 #ifdef CONFIG_FAIR_GROUP_SCHED
@@ -8294,6 +8211,7 @@
 static void normalize_task(struct rq *rq, struct task_struct *p)
 {
 	int on_rq;
+
 	update_rq_clock(rq);
 	on_rq = p->se.on_rq;
 	if (on_rq)
@@ -8325,7 +8243,6 @@
 		p->se.sleep_start		= 0;
 		p->se.block_start		= 0;
 #endif
-		task_rq(p)->clock		= 0;
 
 		if (!rt_task(p)) {
 			/*
@@ -8692,7 +8609,7 @@
 		dequeue_entity(cfs_rq, se, 0);
 
 	se->load.weight = shares;
-	se->load.inv_weight = div64_u64((1ULL<<32), shares);
+	se->load.inv_weight = 0;
 
 	if (on_rq)
 		enqueue_entity(cfs_rq, se, 0);
@@ -8722,13 +8639,10 @@
 	if (!tg->se[0])
 		return -EINVAL;
 
-	/*
-	 * A weight of 0 or 1 can cause arithmetics problems.
-	 * (The default weight is 1024 - so there's no practical
-	 *  limitation from this.)
-	 */
 	if (shares < MIN_SHARES)
 		shares = MIN_SHARES;
+	else if (shares > MAX_SHARES)
+		shares = MAX_SHARES;
 
 	mutex_lock(&shares_mutex);
 	if (tg->shares == shares)
@@ -8753,7 +8667,7 @@
 		 * force a rebalance
 		 */
 		cfs_rq_set_shares(tg->cfs_rq[i], 0);
-		set_se_shares(tg->se[i], shares/nr_cpu_ids);
+		set_se_shares(tg->se[i], shares);
 	}
 
 	/*
@@ -9072,7 +8986,7 @@
 #endif
 
 #ifdef CONFIG_RT_GROUP_SCHED
-static ssize_t cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft,
+static int cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft,
 				s64 val)
 {
 	return sched_group_set_rt_runtime(cgroup_tg(cgrp), val);
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
new file mode 100644
index 0000000..9c597e3
--- /dev/null
+++ b/kernel/sched_clock.c
@@ -0,0 +1,236 @@
+/*
+ * sched_clock for unstable cpu clocks
+ *
+ *  Copyright (C) 2008 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *
+ * Based on code by:
+ *   Ingo Molnar <mingo@redhat.com>
+ *   Guillaume Chazarain <guichaz@gmail.com>
+ *
+ * Create a semi stable clock from a mixture of other events, including:
+ *  - gtod
+ *  - jiffies
+ *  - sched_clock()
+ *  - explicit idle events
+ *
+ * We use gtod as base and the unstable clock deltas. The deltas are filtered,
+ * making it monotonic and keeping it within an expected window.  This window
+ * is set up using jiffies.
+ *
+ * Furthermore, explicit sleep and wakeup hooks allow us to account for time
+ * that is otherwise invisible (TSC gets stopped).
+ *
+ * The clock: sched_clock_cpu() is monotonic per cpu, and should be somewhat
+ * consistent between cpus (never more than 1 jiffies difference).
+ */
+#include <linux/sched.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+
+
+#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
+
+struct sched_clock_data {
+	/*
+	 * Raw spinlock - this is a special case: this might be called
+	 * from within instrumentation code so we dont want to do any
+	 * instrumentation ourselves.
+	 */
+	raw_spinlock_t		lock;
+
+	unsigned long		prev_jiffies;
+	u64			prev_raw;
+	u64			tick_raw;
+	u64			tick_gtod;
+	u64			clock;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct sched_clock_data, sched_clock_data);
+
+static inline struct sched_clock_data *this_scd(void)
+{
+	return &__get_cpu_var(sched_clock_data);
+}
+
+static inline struct sched_clock_data *cpu_sdc(int cpu)
+{
+	return &per_cpu(sched_clock_data, cpu);
+}
+
+void sched_clock_init(void)
+{
+	u64 ktime_now = ktime_to_ns(ktime_get());
+	u64 now = 0;
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		struct sched_clock_data *scd = cpu_sdc(cpu);
+
+		scd->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+		scd->prev_jiffies = jiffies;
+		scd->prev_raw = now;
+		scd->tick_raw = now;
+		scd->tick_gtod = ktime_now;
+		scd->clock = ktime_now;
+	}
+}
+
+/*
+ * update the percpu scd from the raw @now value
+ *
+ *  - filter out backward motion
+ *  - use jiffies to generate a min,max window to clip the raw values
+ */
+static void __update_sched_clock(struct sched_clock_data *scd, u64 now)
+{
+	unsigned long now_jiffies = jiffies;
+	long delta_jiffies = now_jiffies - scd->prev_jiffies;
+	u64 clock = scd->clock;
+	u64 min_clock, max_clock;
+	s64 delta = now - scd->prev_raw;
+
+	WARN_ON_ONCE(!irqs_disabled());
+	min_clock = scd->tick_gtod + delta_jiffies * TICK_NSEC;
+
+	if (unlikely(delta < 0)) {
+		clock++;
+		goto out;
+	}
+
+	max_clock = min_clock + TICK_NSEC;
+
+	if (unlikely(clock + delta > max_clock)) {
+		if (clock < max_clock)
+			clock = max_clock;
+		else
+			clock++;
+	} else {
+		clock += delta;
+	}
+
+ out:
+	if (unlikely(clock < min_clock))
+		clock = min_clock;
+
+	scd->prev_raw = now;
+	scd->prev_jiffies = now_jiffies;
+	scd->clock = clock;
+}
+
+static void lock_double_clock(struct sched_clock_data *data1,
+				struct sched_clock_data *data2)
+{
+	if (data1 < data2) {
+		__raw_spin_lock(&data1->lock);
+		__raw_spin_lock(&data2->lock);
+	} else {
+		__raw_spin_lock(&data2->lock);
+		__raw_spin_lock(&data1->lock);
+	}
+}
+
+u64 sched_clock_cpu(int cpu)
+{
+	struct sched_clock_data *scd = cpu_sdc(cpu);
+	u64 now, clock;
+
+	WARN_ON_ONCE(!irqs_disabled());
+	now = sched_clock();
+
+	if (cpu != raw_smp_processor_id()) {
+		/*
+		 * in order to update a remote cpu's clock based on our
+		 * unstable raw time rebase it against:
+		 *   tick_raw		(offset between raw counters)
+		 *   tick_gotd          (tick offset between cpus)
+		 */
+		struct sched_clock_data *my_scd = this_scd();
+
+		lock_double_clock(scd, my_scd);
+
+		now -= my_scd->tick_raw;
+		now += scd->tick_raw;
+
+		now -= my_scd->tick_gtod;
+		now += scd->tick_gtod;
+
+		__raw_spin_unlock(&my_scd->lock);
+	} else {
+		__raw_spin_lock(&scd->lock);
+	}
+
+	__update_sched_clock(scd, now);
+	clock = scd->clock;
+
+	__raw_spin_unlock(&scd->lock);
+
+	return clock;
+}
+
+void sched_clock_tick(void)
+{
+	struct sched_clock_data *scd = this_scd();
+	u64 now, now_gtod;
+
+	WARN_ON_ONCE(!irqs_disabled());
+
+	now = sched_clock();
+	now_gtod = ktime_to_ns(ktime_get());
+
+	__raw_spin_lock(&scd->lock);
+	__update_sched_clock(scd, now);
+	/*
+	 * update tick_gtod after __update_sched_clock() because that will
+	 * already observe 1 new jiffy; adding a new tick_gtod to that would
+	 * increase the clock 2 jiffies.
+	 */
+	scd->tick_raw = now;
+	scd->tick_gtod = now_gtod;
+	__raw_spin_unlock(&scd->lock);
+}
+
+/*
+ * We are going deep-idle (irqs are disabled):
+ */
+void sched_clock_idle_sleep_event(void)
+{
+	sched_clock_cpu(smp_processor_id());
+}
+EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
+
+/*
+ * We just idled delta nanoseconds (called with irqs disabled):
+ */
+void sched_clock_idle_wakeup_event(u64 delta_ns)
+{
+	struct sched_clock_data *scd = this_scd();
+	u64 now = sched_clock();
+
+	/*
+	 * Override the previous timestamp and ignore all
+	 * sched_clock() deltas that occured while we idled,
+	 * and use the PM-provided delta_ns to advance the
+	 * rq clock:
+	 */
+	__raw_spin_lock(&scd->lock);
+	scd->prev_raw = now;
+	scd->clock += delta_ns;
+	__raw_spin_unlock(&scd->lock);
+
+	touch_softlockup_watchdog();
+}
+EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
+
+#endif
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ * This is default implementation.
+ * Architectures and sub-architectures can override this.
+ */
+unsigned long long __attribute__((weak)) sched_clock(void)
+{
+	return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
+}
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 6b4a125..5f06118 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -204,13 +204,6 @@
 	PN(next_balance);
 	P(curr->pid);
 	PN(clock);
-	PN(idle_clock);
-	PN(prev_clock_raw);
-	P(clock_warps);
-	P(clock_overflows);
-	P(clock_underflows);
-	P(clock_deep_idle_events);
-	PN(clock_max_delta);
 	P(cpu_load[0]);
 	P(cpu_load[1]);
 	P(cpu_load[2]);
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 89fa32b..e24ecd3 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -662,10 +662,15 @@
 	if (!initial) {
 		/* sleeps upto a single latency don't count. */
 		if (sched_feat(NEW_FAIR_SLEEPERS)) {
+			unsigned long thresh = sysctl_sched_latency;
+
+			/*
+			 * convert the sleeper threshold into virtual time
+			 */
 			if (sched_feat(NORMALIZED_SLEEPER))
-				vruntime -= calc_delta_weight(sysctl_sched_latency, se);
-			else
-				vruntime -= sysctl_sched_latency;
+				thresh = calc_delta_fair(thresh, se);
+
+			vruntime -= thresh;
 		}
 
 		/* ensure we never gain time by being placed backwards. */
@@ -682,6 +687,7 @@
 	 * Update run-time statistics of the 'current'.
 	 */
 	update_curr(cfs_rq);
+	account_entity_enqueue(cfs_rq, se);
 
 	if (wakeup) {
 		place_entity(cfs_rq, se, 0);
@@ -692,7 +698,6 @@
 	check_spread(cfs_rq, se);
 	if (se != cfs_rq->curr)
 		__enqueue_entity(cfs_rq, se);
-	account_entity_enqueue(cfs_rq, se);
 }
 
 static void update_avg(u64 *avg, u64 sample)
@@ -841,8 +846,10 @@
 	 * queued ticks are scheduled to match the slice, so don't bother
 	 * validating it and just reschedule.
 	 */
-	if (queued)
-		return resched_task(rq_of(cfs_rq)->curr);
+	if (queued) {
+		resched_task(rq_of(cfs_rq)->curr);
+		return;
+	}
 	/*
 	 * don't let the period tick interfere with the hrtick preemption
 	 */
@@ -957,7 +964,7 @@
 		return;
 
 	if (likely(!sysctl_sched_compat_yield) && curr->policy != SCHED_BATCH) {
-		__update_rq_clock(rq);
+		update_rq_clock(rq);
 		/*
 		 * Update run-time statistics of the 'current'.
 		 */
@@ -1007,7 +1014,7 @@
 	 * sibling runqueue info. This will avoid the checks and cache miss
 	 * penalities associated with that.
 	 */
-	if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1)
+	if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1)
 		return cpu;
 
 	for_each_domain(cpu, sd) {
@@ -1611,30 +1618,6 @@
 };
 
 #ifdef CONFIG_SCHED_DEBUG
-static void
-print_cfs_rq_tasks(struct seq_file *m, struct cfs_rq *cfs_rq, int depth)
-{
-	struct sched_entity *se;
-
-	if (!cfs_rq)
-		return;
-
-	list_for_each_entry_rcu(se, &cfs_rq->tasks, group_node) {
-		int i;
-
-		for (i = depth; i; i--)
-			seq_puts(m, "  ");
-
-		seq_printf(m, "%lu %s %lu\n",
-				se->load.weight,
-				entity_is_task(se) ? "T" : "G",
-				calc_delta_weight(SCHED_LOAD_SCALE, se)
-				);
-		if (!entity_is_task(se))
-			print_cfs_rq_tasks(m, group_cfs_rq(se), depth + 1);
-	}
-}
-
 static void print_cfs_stats(struct seq_file *m, int cpu)
 {
 	struct cfs_rq *cfs_rq;
@@ -1642,9 +1625,6 @@
 	rcu_read_lock();
 	for_each_leaf_cfs_rq(cpu_rq(cpu), cfs_rq)
 		print_cfs_rq(m, cpu, cfs_rq);
-
-	seq_printf(m, "\nWeight tree:\n");
-	print_cfs_rq_tasks(m, &cpu_rq(cpu)->cfs, 1);
 	rcu_read_unlock();
 }
 #endif
diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c
index 2bcafa3..3a4f92d 100644
--- a/kernel/sched_idletask.c
+++ b/kernel/sched_idletask.c
@@ -99,7 +99,7 @@
 /*
  * Simple, special scheduling class for the per-CPU idle tasks:
  */
-const struct sched_class idle_sched_class = {
+static const struct sched_class idle_sched_class = {
 	/* .next is NULL */
 	/* no enqueue/yield_task for idle tasks */
 
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index c2730a5..060e87b 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -1098,11 +1098,14 @@
 	}
 }
 
-
+/*
+ * If we are not running and we are not going to reschedule soon, we should
+ * try to push tasks away now
+ */
 static void task_wake_up_rt(struct rq *rq, struct task_struct *p)
 {
 	if (!task_running(rq, p) &&
-	    (p->prio >= rq->rt.highest_prio) &&
+	    !test_tsk_need_resched(rq->curr) &&
 	    rq->rt.overloaded)
 		push_rt_tasks(rq);
 }
@@ -1309,7 +1312,7 @@
 	p->se.exec_start = rq->clock;
 }
 
-const struct sched_class rt_sched_class = {
+static const struct sched_class rt_sched_class = {
 	.next			= &fair_sched_class,
 	.enqueue_task		= enqueue_task_rt,
 	.dequeue_task		= dequeue_task_rt,
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb
index f2e01ac..a5d4b1d 100644
--- a/lib/Kconfig.kgdb
+++ b/lib/Kconfig.kgdb
@@ -1,4 +1,10 @@
 
+config HAVE_ARCH_KGDB_SHADOW_INFO
+	bool
+
+config HAVE_ARCH_KGDB
+	bool
+
 menuconfig KGDB
 	bool "KGDB: kernel debugging with remote gdb"
 	select FRAME_POINTER
@@ -10,15 +16,10 @@
 	  at http://kgdb.sourceforge.net as well as in DocBook form
 	  in Documentation/DocBook/.  If unsure, say N.
 
-config HAVE_ARCH_KGDB_SHADOW_INFO
-	bool
-
-config HAVE_ARCH_KGDB
-	bool
+if KGDB
 
 config KGDB_SERIAL_CONSOLE
 	tristate "KGDB: use kgdb over the serial console"
-	depends on KGDB
 	select CONSOLE_POLL
 	select MAGIC_SYSRQ
 	default y
@@ -28,7 +29,6 @@
 
 config KGDB_TESTS
 	bool "KGDB: internal test suite"
-	depends on KGDB
 	default n
 	help
 	  This is a kgdb I/O module specifically designed to test
@@ -56,3 +56,5 @@
 	  boot.  See the drivers/misc/kgdbts.c for detailed
 	  information about other strings you could use beyond the
 	  default of V1F100.
+
+endif # KGDB
diff --git a/lib/bitmap.c b/lib/bitmap.c
index c4cb48f..482df94 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -316,22 +316,6 @@
 EXPORT_SYMBOL(bitmap_scnprintf);
 
 /**
- * bitmap_scnprintf_len - return buffer length needed to convert
- * bitmap to an ASCII hex string.
- * @len: number of bits to be converted
- */
-int bitmap_scnprintf_len(unsigned int len)
-{
-	/* we need 9 chars per word for 32 bit words (8 hexdigits + sep/null) */
-	int bitslen = ALIGN(len, CHUNKSZ);
-	int wordlen = CHUNKSZ / 4;
-	int buflen = (bitslen / wordlen) * (wordlen + 1) * sizeof(char);
-
-	return buflen;
-}
-EXPORT_SYMBOL(bitmap_scnprintf_len);
-
-/**
  * __bitmap_parse - convert an ASCII hex string into a bitmap.
  * @buf: pointer to buffer containing string.
  * @buflen: buffer size in bytes.  If string is smaller than this
diff --git a/lib/devres.c b/lib/devres.c
index 26c87c4..72c8909 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -2,7 +2,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 
-static void devm_ioremap_release(struct device *dev, void *res)
+void devm_ioremap_release(struct device *dev, void *res)
 {
 	iounmap(*(void __iomem **)res);
 }
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 3435465..f07c0db 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -12,6 +12,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 
+const char hex_asc[] = "0123456789abcdef";
+EXPORT_SYMBOL(hex_asc);
+
 /**
  * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
  * @buf: data blob to dump
@@ -93,8 +96,8 @@
 		for (j = 0; (j < rowsize) && (j < len) && (lx + 4) < linebuflen;
 		     j++) {
 			ch = ptr[j];
-			linebuf[lx++] = hex_asc(ch >> 4);
-			linebuf[lx++] = hex_asc(ch & 0x0f);
+			linebuf[lx++] = hex_asc_hi(ch);
+			linebuf[lx++] = hex_asc_lo(ch);
 			linebuf[lx++] = ' ';
 		}
 		ascii_column = 3 * rowsize + 2;
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index cd3e825..01a3c22 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -11,79 +11,121 @@
 #include <linux/semaphore.h>
 
 /*
- * The 'big kernel semaphore'
+ * The 'big kernel lock'
  *
- * This mutex is taken and released recursively by lock_kernel()
+ * This spinlock is taken and released recursively by lock_kernel()
  * and unlock_kernel().  It is transparently dropped and reacquired
  * over schedule().  It is used to protect legacy code that hasn't
  * been migrated to a proper locking design yet.
  *
- * Note: code locked by this semaphore will only be serialized against
- * other code using the same locking facility. The code guarantees that
- * the task remains on the same CPU.
- *
  * Don't use in new code.
  */
-static DECLARE_MUTEX(kernel_sem);
+static  __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag);
+
 
 /*
- * Re-acquire the kernel semaphore.
+ * Acquire/release the underlying lock from the scheduler.
  *
- * This function is called with preemption off.
+ * This is called with preemption disabled, and should
+ * return an error value if it cannot get the lock and
+ * TIF_NEED_RESCHED gets set.
  *
- * We are executing in schedule() so the code must be extremely careful
- * about recursion, both due to the down() and due to the enabling of
- * preemption. schedule() will re-check the preemption flag after
- * reacquiring the semaphore.
+ * If it successfully gets the lock, it should increment
+ * the preemption count like any spinlock does.
+ *
+ * (This works on UP too - _raw_spin_trylock will never
+ * return false in that case)
  */
 int __lockfunc __reacquire_kernel_lock(void)
 {
-	struct task_struct *task = current;
-	int saved_lock_depth = task->lock_depth;
-
-	BUG_ON(saved_lock_depth < 0);
-
-	task->lock_depth = -1;
-	preempt_enable_no_resched();
-
-	down(&kernel_sem);
-
+	while (!_raw_spin_trylock(&kernel_flag)) {
+		if (test_thread_flag(TIF_NEED_RESCHED))
+			return -EAGAIN;
+		cpu_relax();
+	}
 	preempt_disable();
-	task->lock_depth = saved_lock_depth;
-
 	return 0;
 }
 
 void __lockfunc __release_kernel_lock(void)
 {
-	up(&kernel_sem);
+	_raw_spin_unlock(&kernel_flag);
+	preempt_enable_no_resched();
 }
 
 /*
- * Getting the big kernel semaphore.
+ * These are the BKL spinlocks - we try to be polite about preemption.
+ * If SMP is not on (ie UP preemption), this all goes away because the
+ * _raw_spin_trylock() will always succeed.
+ */
+#ifdef CONFIG_PREEMPT
+static inline void __lock_kernel(void)
+{
+	preempt_disable();
+	if (unlikely(!_raw_spin_trylock(&kernel_flag))) {
+		/*
+		 * If preemption was disabled even before this
+		 * was called, there's nothing we can be polite
+		 * about - just spin.
+		 */
+		if (preempt_count() > 1) {
+			_raw_spin_lock(&kernel_flag);
+			return;
+		}
+
+		/*
+		 * Otherwise, let's wait for the kernel lock
+		 * with preemption enabled..
+		 */
+		do {
+			preempt_enable();
+			while (spin_is_locked(&kernel_flag))
+				cpu_relax();
+			preempt_disable();
+		} while (!_raw_spin_trylock(&kernel_flag));
+	}
+}
+
+#else
+
+/*
+ * Non-preemption case - just get the spinlock
+ */
+static inline void __lock_kernel(void)
+{
+	_raw_spin_lock(&kernel_flag);
+}
+#endif
+
+static inline void __unlock_kernel(void)
+{
+	/*
+	 * the BKL is not covered by lockdep, so we open-code the
+	 * unlocking sequence (and thus avoid the dep-chain ops):
+	 */
+	_raw_spin_unlock(&kernel_flag);
+	preempt_enable();
+}
+
+/*
+ * Getting the big kernel lock.
+ *
+ * This cannot happen asynchronously, so we only need to
+ * worry about other CPU's.
  */
 void __lockfunc lock_kernel(void)
 {
-	struct task_struct *task = current;
-	int depth = task->lock_depth + 1;
-
+	int depth = current->lock_depth+1;
 	if (likely(!depth))
-		/*
-		 * No recursion worries - we set up lock_depth _after_
-		 */
-		down(&kernel_sem);
-
-	task->lock_depth = depth;
+		__lock_kernel();
+	current->lock_depth = depth;
 }
 
 void __lockfunc unlock_kernel(void)
 {
-	struct task_struct *task = current;
-
-	BUG_ON(task->lock_depth < 0);
-
-	if (likely(--task->lock_depth < 0))
-		up(&kernel_sem);
+	BUG_ON(current->lock_depth < 0);
+	if (likely(--current->lock_depth < 0))
+		__unlock_kernel();
 }
 
 EXPORT_SYMBOL(lock_kernel);
diff --git a/lib/lmb.c b/lib/lmb.c
index 83287d3..867f7b5 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -19,31 +19,42 @@
 
 struct lmb lmb;
 
+static int lmb_debug;
+
+static int __init early_lmb(char *p)
+{
+	if (p && strstr(p, "debug"))
+		lmb_debug = 1;
+	return 0;
+}
+early_param("lmb", early_lmb);
+
 void lmb_dump_all(void)
 {
-#ifdef DEBUG
 	unsigned long i;
 
-	pr_debug("lmb_dump_all:\n");
-	pr_debug("    memory.cnt		  = 0x%lx\n", lmb.memory.cnt);
-	pr_debug("    memory.size		  = 0x%llx\n",
+	if (!lmb_debug)
+		return;
+
+	pr_info("lmb_dump_all:\n");
+	pr_info("    memory.cnt		  = 0x%lx\n", lmb.memory.cnt);
+	pr_info("    memory.size		  = 0x%llx\n",
 	    (unsigned long long)lmb.memory.size);
 	for (i=0; i < lmb.memory.cnt ;i++) {
-		pr_debug("    memory.region[0x%x].base       = 0x%llx\n",
+		pr_info("    memory.region[0x%lx].base       = 0x%llx\n",
 		    i, (unsigned long long)lmb.memory.region[i].base);
-		pr_debug("		      .size     = 0x%llx\n",
+		pr_info("		      .size     = 0x%llx\n",
 		    (unsigned long long)lmb.memory.region[i].size);
 	}
 
-	pr_debug("    reserved.cnt	  = 0x%lx\n", lmb.reserved.cnt);
-	pr_debug("    reserved.size	  = 0x%lx\n", lmb.reserved.size);
+	pr_info("    reserved.cnt	  = 0x%lx\n", lmb.reserved.cnt);
+	pr_info("    reserved.size	  = 0x%lx\n", lmb.reserved.size);
 	for (i=0; i < lmb.reserved.cnt ;i++) {
-		pr_debug("    reserved.region[0x%x].base       = 0x%llx\n",
+		pr_info("    reserved.region[0x%lx].base       = 0x%llx\n",
 		    i, (unsigned long long)lmb.reserved.region[i].base);
-		pr_debug("		      .size     = 0x%llx\n",
+		pr_info("		      .size     = 0x%llx\n",
 		    (unsigned long long)lmb.reserved.region[i].size);
 	}
-#endif /* DEBUG */
 }
 
 static unsigned long lmb_addrs_overlap(u64 base1, u64 size1, u64 base2,
@@ -286,8 +297,7 @@
 		j = lmb_overlaps_region(&lmb.reserved, base, size);
 		if (j < 0) {
 			/* this area isn't reserved, take it */
-			if (lmb_add_region(&lmb.reserved, base,
-					   lmb_align_up(size, align)) < 0)
+			if (lmb_add_region(&lmb.reserved, base, size) < 0)
 				base = ~(u64)0;
 			return base;
 		}
@@ -333,6 +343,10 @@
 	struct lmb_region *mem = &lmb.memory;
 	int i;
 
+	BUG_ON(0 == size);
+
+	size = lmb_align_up(size, align);
+
 	for (i = 0; i < mem->cnt; i++) {
 		u64 ret = lmb_alloc_nid_region(&mem->region[i],
 					       nid_range,
@@ -370,6 +384,8 @@
 
 	BUG_ON(0 == size);
 
+	size = lmb_align_up(size, align);
+
 	/* On some platforms, make sure we allocate lowmem */
 	/* Note that LMB_REAL_LIMIT may be LMB_ALLOC_ANYWHERE */
 	if (max_addr == LMB_ALLOC_ANYWHERE)
@@ -393,8 +409,7 @@
 			j = lmb_overlaps_region(&lmb.reserved, base, size);
 			if (j < 0) {
 				/* this area isn't reserved, take it */
-				if (lmb_add_region(&lmb.reserved, base,
-						   lmb_align_up(size, align)) < 0)
+				if (lmb_add_region(&lmb.reserved, base, size) < 0)
 					return 0;
 				return base;
 			}
diff --git a/lib/parser.c b/lib/parser.c
index 703c8c1..4f0cbc0 100644
--- a/lib/parser.c
+++ b/lib/parser.c
@@ -182,18 +182,25 @@
 }
 
 /**
- * match_strcpy: - copies the characters from a substring_t to a string
- * @to: string to copy characters to.
- * @s: &substring_t to copy
+ * match_strlcpy: - Copy the characters from a substring_t to a sized buffer
+ * @dest: where to copy to
+ * @src: &substring_t to copy
+ * @size: size of destination buffer
  *
- * Description: Copies the set of characters represented by the given
- * &substring_t @s to the c-style string @to. Caller guarantees that @to is
- * large enough to hold the characters of @s.
+ * Description: Copy the characters in &substring_t @src to the
+ * c-style string @dest.  Copy no more than @size - 1 characters, plus
+ * the terminating NUL.  Return length of @src.
  */
-void match_strcpy(char *to, const substring_t *s)
+size_t match_strlcpy(char *dest, const substring_t *src, size_t size)
 {
-	memcpy(to, s->from, s->to - s->from);
-	to[s->to - s->from] = '\0';
+	size_t ret = src->to - src->from;
+
+	if (size) {
+		size_t len = ret >= size ? size - 1 : ret;
+		memcpy(dest, src->from, len);
+		dest[len] = '\0';
+	}
+	return ret;
 }
 
 /**
@@ -206,9 +213,10 @@
  */
 char *match_strdup(const substring_t *s)
 {
-	char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
+	size_t sz = s->to - s->from + 1;
+	char *p = kmalloc(sz, GFP_KERNEL);
 	if (p)
-		match_strcpy(p, s);
+		match_strlcpy(p, s, sz);
 	return p;
 }
 
@@ -216,5 +224,5 @@
 EXPORT_SYMBOL(match_int);
 EXPORT_SYMBOL(match_octal);
 EXPORT_SYMBOL(match_hex);
-EXPORT_SYMBOL(match_strcpy);
+EXPORT_SYMBOL(match_strlcpy);
 EXPORT_SYMBOL(match_strdup);
diff --git a/mm/filemap.c b/mm/filemap.c
index 239d361..1e6a7d3 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1461,6 +1461,11 @@
 	 */
 	ClearPageError(page);
 	error = mapping->a_ops->readpage(file, page);
+	if (!error) {
+		wait_on_page_locked(page);
+		if (!PageUptodate(page))
+			error = -EIO;
+	}
 	page_cache_release(page);
 
 	if (!error || error == AOP_TRUNCATED_PAGE)
@@ -1655,7 +1660,7 @@
 }
 EXPORT_SYMBOL(should_remove_suid);
 
-int __remove_suid(struct dentry *dentry, int kill)
+static int __remove_suid(struct dentry *dentry, int kill)
 {
 	struct iattr newattrs;
 
diff --git a/mm/memory.c b/mm/memory.c
index bbab1e37..fb5608a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -311,6 +311,21 @@
 	if (!new)
 		return -ENOMEM;
 
+	/*
+	 * Ensure all pte setup (eg. pte page lock and page clearing) are
+	 * visible before the pte is made visible to other CPUs by being
+	 * put into page tables.
+	 *
+	 * The other side of the story is the pointer chasing in the page
+	 * table walking code (when walking the page table without locking;
+	 * ie. most of the time). Fortunately, these data accesses consist
+	 * of a chain of data-dependent loads, meaning most CPUs (alpha
+	 * being the notable exception) will already guarantee loads are
+	 * seen in-order. See the alpha page table accessors for the
+	 * smp_read_barrier_depends() barriers in page table walking code.
+	 */
+	smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */
+
 	spin_lock(&mm->page_table_lock);
 	if (!pmd_present(*pmd)) {	/* Has another populated it ? */
 		mm->nr_ptes++;
@@ -329,6 +344,8 @@
 	if (!new)
 		return -ENOMEM;
 
+	smp_wmb(); /* See comment in __pte_alloc */
+
 	spin_lock(&init_mm.page_table_lock);
 	if (!pmd_present(*pmd)) {	/* Has another populated it ? */
 		pmd_populate_kernel(&init_mm, pmd, new);
@@ -969,7 +986,7 @@
 		goto no_page_table;
 	
 	pmd = pmd_offset(pud, address);
-	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+	if (pmd_none(*pmd))
 		goto no_page_table;
 
 	if (pmd_huge(*pmd)) {
@@ -978,6 +995,9 @@
 		goto out;
 	}
 
+	if (unlikely(pmd_bad(*pmd)))
+		goto no_page_table;
+
 	ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
 	if (!ptep)
 		goto out;
@@ -2616,6 +2636,8 @@
 	if (!new)
 		return -ENOMEM;
 
+	smp_wmb(); /* See comment in __pte_alloc */
+
 	spin_lock(&mm->page_table_lock);
 	if (pgd_present(*pgd))		/* Another has populated it */
 		pud_free(mm, new);
@@ -2637,6 +2659,8 @@
 	if (!new)
 		return -ENOMEM;
 
+	smp_wmb(); /* See comment in __pte_alloc */
+
 	spin_lock(&mm->page_table_lock);
 #ifndef __ARCH_HAS_4LEVEL_HACK
 	if (pud_present(*pud))		/* Another has populated it */
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index b17dca7..833f854 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -159,21 +159,58 @@
 }
 #endif /* !CONFIG_SPARSEMEM_VMEMMAP */
 
+static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
+			   unsigned long end_pfn)
+{
+	unsigned long old_zone_end_pfn;
+
+	zone_span_writelock(zone);
+
+	old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
+	if (start_pfn < zone->zone_start_pfn)
+		zone->zone_start_pfn = start_pfn;
+
+	zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
+				zone->zone_start_pfn;
+
+	zone_span_writeunlock(zone);
+}
+
+static void grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn,
+			    unsigned long end_pfn)
+{
+	unsigned long old_pgdat_end_pfn =
+		pgdat->node_start_pfn + pgdat->node_spanned_pages;
+
+	if (start_pfn < pgdat->node_start_pfn)
+		pgdat->node_start_pfn = start_pfn;
+
+	pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
+					pgdat->node_start_pfn;
+}
+
 static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
 {
 	struct pglist_data *pgdat = zone->zone_pgdat;
 	int nr_pages = PAGES_PER_SECTION;
 	int nid = pgdat->node_id;
 	int zone_type;
+	unsigned long flags;
 
 	zone_type = zone - pgdat->node_zones;
 	if (!zone->wait_table) {
-		int ret = 0;
+		int ret;
+
 		ret = init_currently_empty_zone(zone, phys_start_pfn,
 						nr_pages, MEMMAP_HOTPLUG);
-		if (ret < 0)
+		if (ret)
 			return ret;
 	}
+	pgdat_resize_lock(zone->zone_pgdat, &flags);
+	grow_zone_span(zone, phys_start_pfn, phys_start_pfn + nr_pages);
+	grow_pgdat_span(zone->zone_pgdat, phys_start_pfn,
+			phys_start_pfn + nr_pages);
+	pgdat_resize_unlock(zone->zone_pgdat, &flags);
 	memmap_init_zone(nr_pages, nid, zone_type,
 			 phys_start_pfn, MEMMAP_HOTPLUG);
 	return 0;
@@ -299,36 +336,6 @@
 }
 EXPORT_SYMBOL_GPL(__remove_pages);
 
-static void grow_zone_span(struct zone *zone,
-		unsigned long start_pfn, unsigned long end_pfn)
-{
-	unsigned long old_zone_end_pfn;
-
-	zone_span_writelock(zone);
-
-	old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
-	if (start_pfn < zone->zone_start_pfn)
-		zone->zone_start_pfn = start_pfn;
-
-	zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
-				zone->zone_start_pfn;
-
-	zone_span_writeunlock(zone);
-}
-
-static void grow_pgdat_span(struct pglist_data *pgdat,
-		unsigned long start_pfn, unsigned long end_pfn)
-{
-	unsigned long old_pgdat_end_pfn =
-		pgdat->node_start_pfn + pgdat->node_spanned_pages;
-
-	if (start_pfn < pgdat->node_start_pfn)
-		pgdat->node_start_pfn = start_pfn;
-
-	pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
-					pgdat->node_start_pfn;
-}
-
 void online_page(struct page *page)
 {
 	totalram_pages++;
@@ -367,7 +374,6 @@
 
 int online_pages(unsigned long pfn, unsigned long nr_pages)
 {
-	unsigned long flags;
 	unsigned long onlined_pages = 0;
 	struct zone *zone;
 	int need_zonelists_rebuild = 0;
@@ -395,11 +401,6 @@
 	 * memory_block->state_mutex.
 	 */
 	zone = page_zone(pfn_to_page(pfn));
-	pgdat_resize_lock(zone->zone_pgdat, &flags);
-	grow_zone_span(zone, pfn, pfn + nr_pages);
-	grow_pgdat_span(zone->zone_pgdat, pfn, pfn + nr_pages);
-	pgdat_resize_unlock(zone->zone_pgdat, &flags);
-
 	/*
 	 * If this zone is not populated, then it is not in zonelist.
 	 * This means the page allocator ignores this zone.
@@ -408,8 +409,15 @@
 	if (!populated_zone(zone))
 		need_zonelists_rebuild = 1;
 
-	walk_memory_resource(pfn, nr_pages, &onlined_pages,
+	ret = walk_memory_resource(pfn, nr_pages, &onlined_pages,
 		online_pages_range);
+	if (ret) {
+		printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
+			nr_pages, pfn);
+		memory_notify(MEM_CANCEL_ONLINE, &arg);
+		return ret;
+	}
+
 	zone->present_pages += onlined_pages;
 	zone->zone_pgdat->node_present_pages += onlined_pages;
 
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 4de5468..a5bf31c 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -26,6 +26,13 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
+#ifndef pgprot_modify
+static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
+{
+	return newprot;
+}
+#endif
+
 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
 		unsigned long addr, unsigned long end, pgprot_t newprot,
 		int dirty_accountable)
@@ -192,7 +199,9 @@
 	 * held in write mode.
 	 */
 	vma->vm_flags = newflags;
-	vma->vm_page_prot = vm_get_page_prot(newflags);
+	vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
+					  vm_get_page_prot(newflags));
+
 	if (vma_wants_writenotify(vma)) {
 		vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
 		dirty_accountable = 1;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bdd5c43..6383557 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2862,8 +2862,6 @@
 
 	zone->zone_start_pfn = zone_start_pfn;
 
-	memmap_init(size, pgdat->node_id, zone_idx(zone), zone_start_pfn);
-
 	zone_init_free_lists(zone);
 
 	return 0;
@@ -3433,6 +3431,7 @@
 		ret = init_currently_empty_zone(zone, zone_start_pfn,
 						size, MEMMAP_EARLY);
 		BUG_ON(ret);
+		memmap_init(size, nid, j, zone_start_pfn);
 		zone_start_pfn += size;
 	}
 }
diff --git a/mm/pdflush.c b/mm/pdflush.c
index 1c96cfc..9d834aa 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -207,7 +207,6 @@
 
 	spin_lock_irqsave(&pdflush_lock, flags);
 	if (list_empty(&pdflush_list)) {
-		spin_unlock_irqrestore(&pdflush_lock, flags);
 		ret = -1;
 	} else {
 		struct pdflush_work *pdf;
@@ -219,8 +218,9 @@
 		pdf->fn = fn;
 		pdf->arg0 = arg0;
 		wake_up_process(pdf->who);
-		spin_unlock_irqrestore(&pdflush_lock, flags);
 	}
+	spin_unlock_irqrestore(&pdflush_lock, flags);
+
 	return ret;
 }
 
diff --git a/mm/slub.c b/mm/slub.c
index d379b78..a505a82 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3762,7 +3762,7 @@
 		if (!n)
 			continue;
 
-		if (atomic_read(&n->total_objects))
+		if (atomic_long_read(&n->total_objects))
 			return 1;
 	}
 	return 0;
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 1a32130..db9eabb 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -41,7 +41,9 @@
 */
 void all_vm_events(unsigned long *ret)
 {
+	get_online_cpus();
 	sum_vm_events(ret, &cpu_online_map);
+	put_online_cpus();
 }
 EXPORT_SYMBOL_GPL(all_vm_events);
 
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
index bafc50c..ff34c5a 100644
--- a/net/9p/Kconfig
+++ b/net/9p/Kconfig
@@ -13,16 +13,6 @@
 
 	  If unsure, say N.
 
-config NET_9P_FD
-	depends on NET_9P
-	default y if NET_9P
-	tristate "9P File Descriptor Transports (Experimental)"
-	help
-	  This builds support for file descriptor transports for 9p
-	  which includes support for TCP/IP, named pipes, or passed
-	  file descriptors.  TCP/IP is the default transport for 9p,
-	  so if you are going to use 9p, you'll likely want this.
-
 config NET_9P_VIRTIO
 	depends on NET_9P && EXPERIMENTAL && VIRTIO
 	tristate "9P Virtio Transport (Experimental)"
diff --git a/net/9p/Makefile b/net/9p/Makefile
index 8a10511..5192194 100644
--- a/net/9p/Makefile
+++ b/net/9p/Makefile
@@ -1,5 +1,4 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
-obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
 
 9pnet-objs := \
@@ -9,8 +8,6 @@
 	error.o \
 	fcprint.o \
 	util.o \
-
-9pnet_fd-objs := \
 	trans_fd.o \
 
 9pnet_virtio-objs := \
diff --git a/net/9p/client.c b/net/9p/client.c
index 84e087e..2ffe40c 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -64,21 +64,30 @@
  * @options: options string passed from mount
  * @v9ses: existing v9fs session information
  *
+ * Return 0 upon success, -ERRNO upon failure
  */
 
-static void parse_opts(char *options, struct p9_client *clnt)
+static int parse_opts(char *opts, struct p9_client *clnt)
 {
+	char *options;
 	char *p;
 	substring_t args[MAX_OPT_ARGS];
 	int option;
-	int ret;
+	int ret = 0;
 
 	clnt->trans_mod = v9fs_default_trans();
 	clnt->dotu = 1;
 	clnt->msize = 8192;
 
-	if (!options)
-		return;
+	if (!opts)
+		return 0;
+
+	options = kstrdup(opts, GFP_KERNEL);
+	if (!options) {
+		P9_DPRINTK(P9_DEBUG_ERROR,
+				"failed to allocate copy of option string\n");
+		return -ENOMEM;
+	}
 
 	while ((p = strsep(&options, ",")) != NULL) {
 		int token;
@@ -86,10 +95,11 @@
 			continue;
 		token = match_token(p, tokens, args);
 		if (token < Opt_trans) {
-			ret = match_int(&args[0], &option);
-			if (ret < 0) {
+			int r = match_int(&args[0], &option);
+			if (r < 0) {
 				P9_DPRINTK(P9_DEBUG_ERROR,
 					"integer field, but no integer?\n");
+				ret = r;
 				continue;
 			}
 		}
@@ -107,6 +117,8 @@
 			continue;
 		}
 	}
+	kfree(options);
+	return ret;
 }
 
 
@@ -138,16 +150,20 @@
 	if (!clnt)
 		return ERR_PTR(-ENOMEM);
 
+	clnt->trans = NULL;
 	spin_lock_init(&clnt->lock);
 	INIT_LIST_HEAD(&clnt->fidlist);
 	clnt->fidpool = p9_idpool_create();
-	if (!clnt->fidpool) {
+	if (IS_ERR(clnt->fidpool)) {
 		err = PTR_ERR(clnt->fidpool);
 		clnt->fidpool = NULL;
 		goto error;
 	}
 
-	parse_opts(options, clnt);
+	err = parse_opts(options, clnt);
+	if (err < 0)
+		goto error;
+
 	if (clnt->trans_mod == NULL) {
 		err = -EPROTONOSUPPORT;
 		P9_DPRINTK(P9_DEBUG_ERROR,
diff --git a/net/9p/conv.c b/net/9p/conv.c
index 3fe35d5..4454720 100644
--- a/net/9p/conv.c
+++ b/net/9p/conv.c
@@ -197,7 +197,7 @@
 
 /**
  * p9_size_wstat - calculate the size of a variable length stat struct
- * @stat: metadata (stat) structure
+ * @wstat: metadata (stat) structure
  * @dotu: non-zero if 9P2000.u
  *
  */
@@ -511,6 +511,12 @@
 	return fc;
 }
 
+/**
+ * p9_set_tag - set the tag field of an &p9_fcall structure
+ * @fc: fcall structure to set tag within
+ * @tag: tag id to set
+ */
+
 void p9_set_tag(struct p9_fcall *fc, u16 tag)
 {
 	fc->tag = tag;
@@ -518,6 +524,12 @@
 }
 EXPORT_SYMBOL(p9_set_tag);
 
+/**
+ * p9_create_tversion - allocates and creates a T_VERSION request
+ * @msize: requested maximum data size
+ * @version: version string to negotiate
+ *
+ */
 struct p9_fcall *p9_create_tversion(u32 msize, char *version)
 {
 	int size;
@@ -542,6 +554,16 @@
 }
 EXPORT_SYMBOL(p9_create_tversion);
 
+/**
+ * p9_create_tauth - allocates and creates a T_AUTH request
+ * @afid: handle to use for authentication protocol
+ * @uname: user name attempting to authenticate
+ * @aname: mount specifier for remote server
+ * @n_uname: numeric id for user attempting to authneticate
+ * @dotu: 9P2000.u extension flag
+ *
+ */
+
 struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
 	u32 n_uname, int dotu)
 {
@@ -580,6 +602,18 @@
 }
 EXPORT_SYMBOL(p9_create_tauth);
 
+/**
+ * p9_create_tattach - allocates and creates a T_ATTACH request
+ * @fid: handle to use for the new mount point
+ * @afid: handle to use for authentication protocol
+ * @uname: user name attempting to attach
+ * @aname: mount specifier for remote server
+ * @n_uname: numeric id for user attempting to attach
+ * @n_uname: numeric id for user attempting to attach
+ * @dotu: 9P2000.u extension flag
+ *
+ */
+
 struct p9_fcall *
 p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
 	u32 n_uname, int dotu)
@@ -616,6 +650,12 @@
 }
 EXPORT_SYMBOL(p9_create_tattach);
 
+/**
+ * p9_create_tflush - allocates and creates a T_FLUSH request
+ * @oldtag: tag id for the transaction we are attempting to cancel
+ *
+ */
+
 struct p9_fcall *p9_create_tflush(u16 oldtag)
 {
 	int size;
@@ -639,6 +679,15 @@
 }
 EXPORT_SYMBOL(p9_create_tflush);
 
+/**
+ * p9_create_twalk - allocates and creates a T_FLUSH request
+ * @fid: handle we are traversing from
+ * @newfid: a new handle for this transaction
+ * @nwname: number of path elements to traverse
+ * @wnames: array of path elements
+ *
+ */
+
 struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
 				     char **wnames)
 {
@@ -677,6 +726,13 @@
 }
 EXPORT_SYMBOL(p9_create_twalk);
 
+/**
+ * p9_create_topen - allocates and creates a T_OPEN request
+ * @fid: handle we are trying to open
+ * @mode: what mode we are trying to open the file in
+ *
+ */
+
 struct p9_fcall *p9_create_topen(u32 fid, u8 mode)
 {
 	int size;
@@ -701,6 +757,19 @@
 }
 EXPORT_SYMBOL(p9_create_topen);
 
+/**
+ * p9_create_tcreate - allocates and creates a T_CREATE request
+ * @fid: handle of directory we are trying to create in
+ * @name: name of the file we are trying to create
+ * @perm: permissions for the file we are trying to create
+ * @mode: what mode we are trying to open the file in
+ * @extension: 9p2000.u extension string (for special files)
+ * @dotu: 9p2000.u enabled flag
+ *
+ * Note: Plan 9 create semantics include opening the resulting file
+ * which is why mode is included.
+ */
+
 struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
 	char *extension, int dotu)
 {
@@ -736,6 +805,13 @@
 }
 EXPORT_SYMBOL(p9_create_tcreate);
 
+/**
+ * p9_create_tread - allocates and creates a T_READ request
+ * @fid: handle of the file we are trying to read
+ * @offset: offset to start reading from
+ * @count: how many bytes to read
+ */
+
 struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count)
 {
 	int size;
@@ -761,6 +837,17 @@
 }
 EXPORT_SYMBOL(p9_create_tread);
 
+/**
+ * p9_create_twrite - allocates and creates a T_WRITE request from the kernel
+ * @fid: handle of the file we are trying to write
+ * @offset: offset to start writing at
+ * @count: how many bytes to write
+ * @data: data to write
+ *
+ * This function will create a requst with data buffers from the kernel
+ * such as the page cache.
+ */
+
 struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
 				      const char *data)
 {
@@ -794,6 +881,16 @@
 }
 EXPORT_SYMBOL(p9_create_twrite);
 
+/**
+ * p9_create_twrite_u - allocates and creates a T_WRITE request from userspace
+ * @fid: handle of the file we are trying to write
+ * @offset: offset to start writing at
+ * @count: how many bytes to write
+ * @data: data to write
+ *
+ * This function will create a request with data buffers from userspace
+ */
+
 struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
 				      const char __user *data)
 {
@@ -827,6 +924,14 @@
 }
 EXPORT_SYMBOL(p9_create_twrite_u);
 
+/**
+ * p9_create_tclunk - allocate a request to forget about a file handle
+ * @fid: handle of the file we closing or forgetting about
+ *
+ * clunk is used both to close open files and to discard transient handles
+ * which may be created during meta-data operations and hierarchy traversal.
+ */
+
 struct p9_fcall *p9_create_tclunk(u32 fid)
 {
 	int size;
@@ -850,6 +955,12 @@
 }
 EXPORT_SYMBOL(p9_create_tclunk);
 
+/**
+ * p9_create_tremove - allocate and create a request to remove a file
+ * @fid: handle of the file or directory we are removing
+ *
+ */
+
 struct p9_fcall *p9_create_tremove(u32 fid)
 {
 	int size;
@@ -873,6 +984,12 @@
 }
 EXPORT_SYMBOL(p9_create_tremove);
 
+/**
+ * p9_create_tstat - allocate and populate a request for attributes
+ * @fid: handle of the file or directory we are trying to get the attributes of
+ *
+ */
+
 struct p9_fcall *p9_create_tstat(u32 fid)
 {
 	int size;
@@ -896,6 +1013,14 @@
 }
 EXPORT_SYMBOL(p9_create_tstat);
 
+/**
+ * p9_create_tstat - allocate and populate a request to change attributes
+ * @fid: handle of the file or directory we are trying to change
+ * @wstat: &p9_stat structure with attributes we wish to set
+ * @dotu: 9p2000.u enabled flag
+ *
+ */
+
 struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
 				      int dotu)
 {
@@ -922,3 +1047,4 @@
 	return fc;
 }
 EXPORT_SYMBOL(p9_create_twstat);
+
diff --git a/net/9p/error.c b/net/9p/error.c
index 64104b9..fdebe43 100644
--- a/net/9p/error.c
+++ b/net/9p/error.c
@@ -33,6 +33,13 @@
 #include <linux/errno.h>
 #include <net/9p/9p.h>
 
+/**
+ * struct errormap - map string errors from Plan 9 to Linux numeric ids
+ * @name: string sent over 9P
+ * @val: numeric id most closely representing @name
+ * @namelen: length of string
+ * @list: hash-table list for string lookup
+ */
 struct errormap {
 	char *name;
 	int val;
@@ -177,8 +184,7 @@
 };
 
 /**
- * p9_error_init - preload
- * @errstr: error string
+ * p9_error_init - preload mappings into hash list
  *
  */
 
@@ -206,6 +212,7 @@
 /**
  * errstr2errno - convert error string to error number
  * @errstr: error string
+ * @len: length of error string
  *
  */
 
@@ -230,8 +237,8 @@
 	if (errno == 0) {
 		/* TODO: if error isn't found, add it dynamically */
 		errstr[len] = 0;
-		printk(KERN_ERR "%s: errstr :%s: not found\n", __func__,
-		       errstr);
+		printk(KERN_ERR "%s: server reported unknown error %s\n",
+			__func__, errstr);
 		errno = 1;
 	}
 
diff --git a/net/9p/fcprint.c b/net/9p/fcprint.c
index 40244fb..53dd8e2 100644
--- a/net/9p/fcprint.c
+++ b/net/9p/fcprint.c
@@ -142,6 +142,14 @@
 	return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16);
 }
 
+/**
+ * p9_printfcall - decode and print a protocol structure into a buffer
+ * @buf: buffer to deposit decoded structure into
+ * @buflen: available space in buffer
+ * @fc: protocol rpc structure of type &p9_fcall
+ * @extended: whether or not session is operating with extended protocol
+ */
+
 int
 p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
 {
diff --git a/net/9p/mod.c b/net/9p/mod.c
index c285aab..bdee1fb 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -39,9 +39,6 @@
 MODULE_PARM_DESC(debug, "9P debugging level");
 #endif
 
-extern int p9_mux_global_init(void);
-extern void p9_mux_global_exit(void);
-
 /*
  * Dynamic Transport Registration Routines
  *
@@ -52,7 +49,7 @@
 
 /**
  * v9fs_register_trans - register a new transport with 9p
- * @m - structure describing the transport module and entry points
+ * @m: structure describing the transport module and entry points
  *
  */
 void v9fs_register_trans(struct p9_trans_module *m)
@@ -65,7 +62,7 @@
 
 /**
  * v9fs_match_trans - match transport versus registered transports
- * @arg: string identifying transport
+ * @name: string identifying transport
  *
  */
 struct p9_trans_module *v9fs_match_trans(const substring_t *name)
@@ -110,6 +107,7 @@
 
 	p9_error_init();
 	printk(KERN_INFO "Installing 9P2000 support\n");
+	p9_trans_fd_init();
 
 	return ret;
 }
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index f624dff..4507f74 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -47,12 +47,29 @@
 #define SCHED_TIMEOUT	10
 #define MAXPOLLWADDR	2
 
+/**
+ * struct p9_fd_opts - per-transport options
+ * @rfd: file descriptor for reading (trans=fd)
+ * @wfd: file descriptor for writing (trans=fd)
+ * @port: port to connect to (trans=tcp)
+ *
+ */
+
 struct p9_fd_opts {
 	int rfd;
 	int wfd;
 	u16 port;
 };
 
+
+/**
+ * struct p9_trans_fd - transport state
+ * @rd: reference to file to read from
+ * @wr: reference of file to write to
+ * @conn: connection state reference
+ *
+ */
+
 struct p9_trans_fd {
 	struct file *rd;
 	struct file *wr;
@@ -90,10 +107,24 @@
 };
 
 struct p9_req;
-
 typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
+
+/**
+ * struct p9_req - fd mux encoding of an rpc transaction
+ * @lock: protects req_list
+ * @tag: numeric tag for rpc transaction
+ * @tcall: request &p9_fcall structure
+ * @rcall: response &p9_fcall structure
+ * @err: error state
+ * @cb: callback for when response is received
+ * @cba: argument to pass to callback
+ * @flush: flag to indicate RPC has been flushed
+ * @req_list: list link for higher level objects to chain requests
+ *
+ */
+
 struct p9_req {
-	spinlock_t lock; /* protect request structure */
+	spinlock_t lock;
 	int tag;
 	struct p9_fcall *tcall;
 	struct p9_fcall *rcall;
@@ -104,7 +135,39 @@
 	struct list_head req_list;
 };
 
-struct p9_mux_poll_task;
+struct p9_mux_poll_task {
+	struct task_struct *task;
+	struct list_head mux_list;
+	int muxnum;
+};
+
+/**
+ * struct p9_conn - fd mux connection state information
+ * @lock: protects mux_list (?)
+ * @mux_list: list link for mux to manage multiple connections (?)
+ * @poll_task: task polling on this connection
+ * @msize: maximum size for connection (dup)
+ * @extended: 9p2000.u flag (dup)
+ * @trans: reference to transport instance for this connection
+ * @tagpool: id accounting for transactions
+ * @err: error state
+ * @equeue: event wait_q (?)
+ * @req_list: accounting for requests which have been sent
+ * @unsent_req_list: accounting for requests that haven't been sent
+ * @rcall: current response &p9_fcall structure
+ * @rpos: read position in current frame
+ * @rbuf: current read buffer
+ * @wpos: write position for current frame
+ * @wsize: amount of data to write for current frame
+ * @wbuf: current write buffer
+ * @poll_wait: array of wait_q's for various worker threads
+ * @poll_waddr: ????
+ * @pt: poll state
+ * @rq: current read work
+ * @wq: current write work
+ * @wsched: ????
+ *
+ */
 
 struct p9_conn {
 	spinlock_t lock; /* protect lock structure */
@@ -132,11 +195,16 @@
 	unsigned long wsched;
 };
 
-struct p9_mux_poll_task {
-	struct task_struct *task;
-	struct list_head mux_list;
-	int muxnum;
-};
+/**
+ * struct p9_mux_rpc - fd mux rpc accounting structure
+ * @m: connection this request was issued on
+ * @err: error state
+ * @tcall: request &p9_fcall
+ * @rcall: response &p9_fcall
+ * @wqueue: wait queue that client is blocked on for this rpc
+ *
+ * Bug: isn't this information duplicated elsewhere like &p9_req
+ */
 
 struct p9_mux_rpc {
 	struct p9_conn *m;
@@ -207,10 +275,12 @@
 
 /**
  * p9_mux_calc_poll_procs - calculates the number of polling procs
- * based on the number of mounted v9fs filesystems.
+ * @muxnum: number of mounts
  *
+ * Calculation is based on the number of mounted v9fs filesystems.
  * The current implementation returns sqrt of the number of mounts.
  */
+
 static int p9_mux_calc_poll_procs(int muxnum)
 {
 	int n;
@@ -331,12 +401,11 @@
 
 /**
  * p9_conn_create - allocate and initialize the per-session mux data
- * Creates the polling task if this is the first session.
+ * @trans: transport structure
  *
- * @trans - transport structure
- * @msize - maximum message size
- * @extended - extended flag
+ * Note: Creates the polling task if this is the first session.
  */
+
 static struct p9_conn *p9_conn_create(struct p9_trans *trans)
 {
 	int i, n;
@@ -406,7 +475,10 @@
 
 /**
  * p9_mux_destroy - cancels all pending requests and frees mux resources
+ * @m: mux to destroy
+ *
  */
+
 static void p9_conn_destroy(struct p9_conn *m)
 {
 	P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
@@ -429,9 +501,14 @@
 }
 
 /**
- * p9_pollwait - called by files poll operation to add v9fs-poll task
- * 	to files wait queue
+ * p9_pollwait - add poll task to the wait queue
+ * @filp: file pointer being polled
+ * @wait_address: wait_q to block on
+ * @p: poll state
+ *
+ * called by files poll operation to add v9fs-poll task to files wait queue
  */
+
 static void
 p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
 {
@@ -462,7 +539,10 @@
 
 /**
  * p9_poll_mux - polls a mux and schedules read or write works if necessary
+ * @m: connection to poll
+ *
  */
+
 static void p9_poll_mux(struct p9_conn *m)
 {
 	int n;
@@ -499,9 +579,14 @@
 }
 
 /**
- * p9_poll_proc - polls all v9fs transports for new events and queues
- * 	the appropriate work to the work queue
+ * p9_poll_proc - poll worker thread
+ * @a: thread state and arguments
+ *
+ * polls all v9fs transports for new events and queues the appropriate
+ * work to the work queue
+ *
  */
+
 static int p9_poll_proc(void *a)
 {
 	struct p9_conn *m, *mtmp;
@@ -527,7 +612,10 @@
 
 /**
  * p9_write_work - called when a transport can send some data
+ * @work: container for work to be done
+ *
  */
+
 static void p9_write_work(struct work_struct *work)
 {
 	int n, err;
@@ -638,7 +726,10 @@
 
 /**
  * p9_read_work - called when there is some data to be read from a transport
+ * @work: container of work to be done
+ *
  */
+
 static void p9_read_work(struct work_struct *work)
 {
 	int n, err;
@@ -793,7 +884,9 @@
  * @tc: request to be sent
  * @cb: callback function to call when response is received
  * @cba: parameter to pass to the callback function
+ *
  */
+
 static struct p9_req *p9_send_request(struct p9_conn *m,
 					  struct p9_fcall *tc,
 					  p9_conn_req_callback cb, void *cba)
@@ -961,10 +1054,12 @@
 /**
  * p9_fd_rpc- sends 9P request and waits until a response is available.
  *	The function can be interrupted.
- * @m: mux data
+ * @t: transport data
  * @tc: request to be sent
  * @rc: pointer where a pointer to the response is stored
+ *
  */
+
 int
 p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
 {
@@ -1041,8 +1136,10 @@
  * @m: mux data
  * @tc: request to be sent
  * @cb: callback function to be called when response arrives
- * @cba: value to pass to the callback function
+ * @a: value to pass to the callback function
+ *
  */
+
 int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
 		   p9_conn_req_callback cb, void *a)
 {
@@ -1065,7 +1162,9 @@
  * p9_conn_cancel - cancel all pending requests with error
  * @m: mux data
  * @err: error code
+ *
  */
+
 void p9_conn_cancel(struct p9_conn *m, int err)
 {
 	struct p9_req *req, *rtmp;
@@ -1097,35 +1196,46 @@
 }
 
 /**
- * v9fs_parse_options - parse mount options into session structure
+ * parse_options - parse mount options into session structure
  * @options: options string passed from mount
- * @v9ses: existing v9fs session information
+ * @opts: transport-specific structure to parse options into
  *
+ * Returns 0 upon success, -ERRNO upon failure
  */
 
-static void parse_opts(char *options, struct p9_fd_opts *opts)
+static int parse_opts(char *params, struct p9_fd_opts *opts)
 {
 	char *p;
 	substring_t args[MAX_OPT_ARGS];
 	int option;
+	char *options;
 	int ret;
 
 	opts->port = P9_PORT;
 	opts->rfd = ~0;
 	opts->wfd = ~0;
 
-	if (!options)
-		return;
+	if (!params)
+		return 0;
+
+	options = kstrdup(params, GFP_KERNEL);
+	if (!options) {
+		P9_DPRINTK(P9_DEBUG_ERROR,
+				"failed to allocate copy of option string\n");
+		return -ENOMEM;
+	}
 
 	while ((p = strsep(&options, ",")) != NULL) {
 		int token;
+		int r;
 		if (!*p)
 			continue;
 		token = match_token(p, tokens, args);
-		ret = match_int(&args[0], &option);
-		if (ret < 0) {
+		r = match_int(&args[0], &option);
+		if (r < 0) {
 			P9_DPRINTK(P9_DEBUG_ERROR,
 			 "integer field, but no integer?\n");
+			ret = r;
 			continue;
 		}
 		switch (token) {
@@ -1142,6 +1252,8 @@
 			continue;
 		}
 	}
+	kfree(options);
+	return 0;
 }
 
 static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
@@ -1193,11 +1305,12 @@
 
 /**
  * p9_fd_read- read from a fd
- * @v9ses: session information
+ * @trans: transport instance state
  * @v: buffer to receive data into
  * @len: size of receive buffer
  *
  */
+
 static int p9_fd_read(struct p9_trans *trans, void *v, int len)
 {
 	int ret;
@@ -1220,11 +1333,12 @@
 
 /**
  * p9_fd_write - write to a socket
- * @v9ses: session information
+ * @trans: transport instance state
  * @v: buffer to send data from
  * @len: size of send buffer
  *
  */
+
 static int p9_fd_write(struct p9_trans *trans, void *v, int len)
 {
 	int ret;
@@ -1296,6 +1410,7 @@
  * @trans: private socket structure
  *
  */
+
 static void p9_fd_close(struct p9_trans *trans)
 {
 	struct p9_trans_fd *ts;
@@ -1318,6 +1433,23 @@
 	kfree(ts);
 }
 
+/*
+ * stolen from NFS - maybe should be made a generic function?
+ */
+static inline int valid_ipaddr4(const char *buf)
+{
+	int rc, count, in[4];
+
+	rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
+	if (rc != 4)
+		return -EINVAL;
+	for (count = 0; count < 4; count++) {
+		if (in[count] > 255)
+			return -EINVAL;
+	}
+	return 0;
+}
+
 static struct p9_trans *
 p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
 {
@@ -1328,7 +1460,12 @@
 	struct p9_fd_opts opts;
 	struct p9_trans_fd *p;
 
-	parse_opts(args, &opts);
+	err = parse_opts(args, &opts);
+	if (err < 0)
+		return ERR_PTR(err);
+
+	if (valid_ipaddr4(addr) < 0)
+		return ERR_PTR(-EINVAL);
 
 	csocket = NULL;
 	trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
@@ -1508,7 +1645,7 @@
 	.create = p9_trans_create_fd,
 };
 
-static int __init p9_trans_fd_init(void)
+int p9_trans_fd_init(void)
 {
 	int ret = p9_mux_global_init();
 	if (ret) {
@@ -1522,9 +1659,4 @@
 
 	return 0;
 }
-
-module_init(p9_trans_fd_init);
-
-MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
-MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
-MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(p9_trans_fd_init);
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index de7a9f5..42adc05 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -49,29 +49,75 @@
 #define VIRTQUEUE_NUM	128
 
 /* a single mutex to manage channel initialization and attachment */
-static DECLARE_MUTEX(virtio_9p_lock);
+static DEFINE_MUTEX(virtio_9p_lock);
 /* global which tracks highest initialized channel */
 static int chan_index;
 
 #define P9_INIT_MAXTAG	16
 
-#define REQ_STATUS_IDLE	0
-#define REQ_STATUS_SENT 1
-#define REQ_STATUS_RCVD 2
-#define REQ_STATUS_FLSH 3
+
+/**
+ * enum p9_req_status_t - virtio request status
+ * @REQ_STATUS_IDLE: request slot unused
+ * @REQ_STATUS_SENT: request sent to server
+ * @REQ_STATUS_RCVD: response received from server
+ * @REQ_STATUS_FLSH: request has been flushed
+ *
+ * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
+ * but use is actually tracked by the idpool structure which handles tag
+ * id allocation.
+ *
+ */
+
+enum p9_req_status_t {
+	REQ_STATUS_IDLE,
+	REQ_STATUS_SENT,
+	REQ_STATUS_RCVD,
+	REQ_STATUS_FLSH,
+};
+
+/**
+ * struct p9_req_t - virtio request slots
+ * @status: status of this request slot
+ * @wq: wait_queue for the client to block on for this request
+ *
+ * The virtio transport uses an array to track outstanding requests
+ * instead of a list.  While this may incurr overhead during initial
+ * allocation or expansion, it makes request lookup much easier as the
+ * tag id is a index into an array.  (We use tag+1 so that we can accomodate
+ * the -1 tag for the T_VERSION request).
+ * This also has the nice effect of only having to allocate wait_queues
+ * once, instead of constantly allocating and freeing them.  Its possible
+ * other resources could benefit from this scheme as well.
+ *
+ */
 
 struct p9_req_t {
 	int status;
 	wait_queue_head_t *wq;
 };
 
-/* We keep all per-channel information in a structure.
+/**
+ * struct virtio_chan - per-instance transport information
+ * @initialized: whether the channel is initialized
+ * @inuse: whether the channel is in use
+ * @lock: protects multiple elements within this structure
+ * @vdev: virtio dev associated with this channel
+ * @vq: virtio queue associated with this channel
+ * @tagpool: accounting for tag ids (and request slots)
+ * @reqs: array of request slots
+ * @max_tag: current number of request_slots allocated
+ * @sg: scatter gather list which is used to pack a request (protected?)
+ *
+ * We keep all per-channel information in a structure.
  * This structure is allocated within the devices dev->mem space.
  * A pointer to the structure will get put in the transport private.
+ *
  */
+
 static struct virtio_chan {
-	bool initialized;		/* channel is initialized */
-	bool inuse;			/* channel is in use */
+	bool initialized;
+	bool inuse;
 
 	spinlock_t lock;
 
@@ -86,7 +132,19 @@
 	struct scatterlist sg[VIRTQUEUE_NUM];
 } channels[MAX_9P_CHAN];
 
-/* Lookup requests by tag */
+/**
+ * p9_lookup_tag - Lookup requests by tag
+ * @c: virtio channel to lookup tag within
+ * @tag: numeric id for transaction
+ *
+ * this is a simple array lookup, but will grow the
+ * request_slots as necessary to accomodate transaction
+ * ids which did not previously have a slot.
+ *
+ * Bugs: there is currently no upper limit on request slots set
+ * here, but that should be constrained by the id accounting.
+ */
+
 static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag)
 {
 	/* This looks up the original request by tag so we know which
@@ -130,11 +188,20 @@
 	return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
 }
 
+/**
+ * p9_virtio_close - reclaim resources of a channel
+ * @trans: transport state
+ *
+ * This reclaims a channel by freeing its resources and
+ * reseting its inuse flag.
+ *
+ */
+
 static void p9_virtio_close(struct p9_trans *trans)
 {
 	struct virtio_chan *chan = trans->priv;
 	int count;
-	unsigned int flags;
+	unsigned long flags;
 
 	spin_lock_irqsave(&chan->lock, flags);
 	p9_idpool_destroy(chan->tagpool);
@@ -144,13 +211,26 @@
 	chan->max_tag = 0;
 	spin_unlock_irqrestore(&chan->lock, flags);
 
-	down(&virtio_9p_lock);
+	mutex_lock(&virtio_9p_lock);
 	chan->inuse = false;
-	up(&virtio_9p_lock);
+	mutex_unlock(&virtio_9p_lock);
 
 	kfree(trans);
 }
 
+/**
+ * req_done - callback which signals activity from the server
+ * @vq: virtio queue activity was received on
+ *
+ * This notifies us that the server has triggered some activity
+ * on the virtio channel - most likely a response to request we
+ * sent.  Figure out which requests now have responses and wake up
+ * those threads.
+ *
+ * Bugs: could do with some additional sanity checking, but appears to work.
+ *
+ */
+
 static void req_done(struct virtqueue *vq)
 {
 	struct virtio_chan *chan = vq->vdev->priv;
@@ -169,6 +249,20 @@
 	spin_unlock_irqrestore(&chan->lock, flags);
 }
 
+/**
+ * pack_sg_list - pack a scatter gather list from a linear buffer
+ * @sg: scatter/gather list to pack into
+ * @start: which segment of the sg_list to start at
+ * @limit: maximum segment to pack data to
+ * @data: data to pack into scatter/gather list
+ * @count: amount of data to pack into the scatter/gather list
+ *
+ * sg_lists have multiple segments of various sizes.  This will pack
+ * arbitrary data into an existing scatter gather list, segmenting the
+ * data as necessary within constraints.
+ *
+ */
+
 static int
 pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
 								int count)
@@ -189,6 +283,14 @@
 	return index-start;
 }
 
+/**
+ * p9_virtio_rpc - issue a request and wait for a response
+ * @t: transport state
+ * @tc: &p9_fcall request to transmit
+ * @rc: &p9_fcall to put reponse into
+ *
+ */
+
 static int
 p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
 {
@@ -263,16 +365,26 @@
 	return 0;
 }
 
+/**
+ * p9_virtio_probe - probe for existence of 9P virtio channels
+ * @vdev: virtio device to probe
+ *
+ * This probes for existing virtio channels.  At present only
+ * a single channel is in use, so in the future more work may need
+ * to be done here.
+ *
+ */
+
 static int p9_virtio_probe(struct virtio_device *vdev)
 {
 	int err;
 	struct virtio_chan *chan;
 	int index;
 
-	down(&virtio_9p_lock);
+	mutex_lock(&virtio_9p_lock);
 	index = chan_index++;
 	chan = &channels[index];
-	up(&virtio_9p_lock);
+	mutex_unlock(&virtio_9p_lock);
 
 	if (chan_index > MAX_9P_CHAN) {
 		printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n");
@@ -301,17 +413,34 @@
 out_free_vq:
 	vdev->config->del_vq(chan->vq);
 fail:
-	down(&virtio_9p_lock);
+	mutex_lock(&virtio_9p_lock);
 	chan_index--;
-	up(&virtio_9p_lock);
+	mutex_unlock(&virtio_9p_lock);
 	return err;
 }
 
-/* This sets up a transport channel for 9p communication.  Right now
+
+/**
+ * p9_virtio_create - allocate a new virtio channel
+ * @devname: string identifying the channel to connect to (unused)
+ * @args: args passed from sys_mount() for per-transport options (unused)
+ * @msize: requested maximum packet size
+ * @extended: 9p2000.u enabled flag
+ *
+ * This sets up a transport channel for 9p communication.  Right now
  * we only match the first available channel, but eventually we couldlook up
  * alternate channels by matching devname versus a virtio_config entry.
  * We use a simple reference count mechanism to ensure that only a single
- * mount has a channel open at a time. */
+ * mount has a channel open at a time.
+ *
+ * Bugs: doesn't allow identification of a specific channel
+ * to allocate, channels are allocated sequentially. This was
+ * a pragmatic decision to get things rolling, but ideally some
+ * way of identifying the channel to attach to would be nice
+ * if we are going to support multiple channels.
+ *
+ */
+
 static struct p9_trans *
 p9_virtio_create(const char *devname, char *args, int msize,
 							unsigned char extended)
@@ -320,7 +449,7 @@
 	struct virtio_chan *chan = channels;
 	int index = 0;
 
-	down(&virtio_9p_lock);
+	mutex_lock(&virtio_9p_lock);
 	while (index < MAX_9P_CHAN) {
 		if (chan->initialized && !chan->inuse) {
 			chan->inuse = true;
@@ -330,7 +459,7 @@
 			chan = &channels[index];
 		}
 	}
-	up(&virtio_9p_lock);
+	mutex_unlock(&virtio_9p_lock);
 
 	if (index >= MAX_9P_CHAN) {
 		printk(KERN_ERR "9p: no channels available\n");
@@ -360,6 +489,12 @@
 	return trans;
 }
 
+/**
+ * p9_virtio_remove - clean up resources associated with a virtio device
+ * @vdev: virtio device to remove
+ *
+ */
+
 static void p9_virtio_remove(struct virtio_device *vdev)
 {
 	struct virtio_chan *chan = vdev->priv;
diff --git a/net/9p/util.c b/net/9p/util.c
index ef72155..958fc58 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -32,11 +32,23 @@
 #include <linux/idr.h>
 #include <net/9p/9p.h>
 
+/**
+ * struct p9_idpool - per-connection accounting for tag idpool
+ * @lock: protects the pool
+ * @pool: idr to allocate tag id from
+ *
+ */
+
 struct p9_idpool {
 	spinlock_t lock;
 	struct idr pool;
 };
 
+/**
+ * p9_idpool_create - create a new per-connection id pool
+ *
+ */
+
 struct p9_idpool *p9_idpool_create(void)
 {
 	struct p9_idpool *p;
@@ -52,6 +64,11 @@
 }
 EXPORT_SYMBOL(p9_idpool_create);
 
+/**
+ * p9_idpool_destroy - create a new per-connection id pool
+ * @p: idpool to destory
+ */
+
 void p9_idpool_destroy(struct p9_idpool *p)
 {
 	idr_destroy(&p->pool);
@@ -61,9 +78,9 @@
 
 /**
  * p9_idpool_get - allocate numeric id from pool
- * @p - pool to allocate from
+ * @p: pool to allocate from
  *
- * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * Bugs: This seems to be an awful generic function, should it be in idr.c with
  *            the lock included in struct idr?
  */
 
@@ -71,7 +88,7 @@
 {
 	int i = 0;
 	int error;
-	unsigned int flags;
+	unsigned long flags;
 
 retry:
 	if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
@@ -94,15 +111,16 @@
 
 /**
  * p9_idpool_put - release numeric id from pool
- * @p - pool to allocate from
+ * @id: numeric id which is being released
+ * @p: pool to release id into
  *
- * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * Bugs: This seems to be an awful generic function, should it be in idr.c with
  *            the lock included in struct idr?
  */
 
 void p9_idpool_put(int id, struct p9_idpool *p)
 {
-	unsigned int flags;
+	unsigned long flags;
 	spin_lock_irqsave(&p->lock, flags);
 	idr_remove(&p->pool, id);
 	spin_unlock_irqrestore(&p->lock, flags);
@@ -111,11 +129,13 @@
 
 /**
  * p9_idpool_check - check if the specified id is available
- * @id - id to check
- * @p - pool
+ * @id: id to check
+ * @p: pool to check
  */
+
 int p9_idpool_check(int id, struct p9_idpool *p)
 {
 	return idr_find(&p->pool, id) != NULL;
 }
 EXPORT_SYMBOL(p9_idpool_check);
+
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 1b22806..9d52ebf 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -346,9 +346,9 @@
 		/* skb==NULL means VCC is being destroyed */
 		br2684_close_vcc(brvcc);
 		if (list_empty(&brdev->brvccs)) {
-			read_lock(&devs_lock);
+			write_lock_irq(&devs_lock);
 			list_del(&brdev->br2684_devs);
-			read_unlock(&devs_lock);
+			write_unlock_irq(&devs_lock);
 			unregister_netdev(net_dev);
 			free_netdev(net_dev);
 		}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 77a981a..c2397f5 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -273,15 +273,13 @@
 	rtnl_lock();
 	if (strchr(dev->name, '%')) {
 		ret = dev_alloc_name(dev, dev->name);
-		if (ret < 0) {
-			free_netdev(dev);
-			goto out;
-		}
+		if (ret < 0)
+			goto out_free;
 	}
 
 	ret = register_netdevice(dev);
 	if (ret)
-		goto out;
+		goto out_free;
 
 	ret = br_sysfs_addbr(dev);
 	if (ret)
@@ -289,6 +287,10 @@
  out:
 	rtnl_unlock();
 	return ret;
+
+out_free:
+	free_netdev(dev);
+	goto out;
 }
 
 int br_del_bridge(const char *name)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 2759b76..7e8ca28 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -208,6 +208,7 @@
  */
 int can_send(struct sk_buff *skb, int loop)
 {
+	struct sk_buff *newskb = NULL;
 	int err;
 
 	if (skb->dev->type != ARPHRD_CAN) {
@@ -244,8 +245,7 @@
 			 * If the interface is not capable to do loopback
 			 * itself, we do it here.
 			 */
-			struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
-
+			newskb = skb_clone(skb, GFP_ATOMIC);
 			if (!newskb) {
 				kfree_skb(skb);
 				return -ENOMEM;
@@ -254,7 +254,6 @@
 			newskb->sk = skb->sk;
 			newskb->ip_summed = CHECKSUM_UNNECESSARY;
 			newskb->pkt_type = PACKET_BROADCAST;
-			netif_rx(newskb);
 		}
 	} else {
 		/* indication for the CAN driver: no loopback required */
@@ -266,11 +265,20 @@
 	if (err > 0)
 		err = net_xmit_errno(err);
 
+	if (err) {
+		if (newskb)
+			kfree_skb(newskb);
+		return err;
+	}
+
+	if (newskb)
+		netif_rx(newskb);
+
 	/* update statistics */
 	can_stats.tx_frames++;
 	can_stats.tx_frames_delta++;
 
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL(can_send);
 
diff --git a/net/core/dev.c b/net/core/dev.c
index d334446..ce88c0d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -903,7 +903,11 @@
 		strlcpy(dev->name, newname, IFNAMSIZ);
 
 rollback:
-	device_rename(&dev->dev, dev->name);
+	err = device_rename(&dev->dev, dev->name);
+	if (err) {
+		memcpy(dev->name, oldname, IFNAMSIZ);
+		return err;
+	}
 
 	write_lock_bh(&dev_base_lock);
 	hlist_del(&dev->name_hlist);
@@ -994,6 +998,8 @@
 {
 	int ret = 0;
 
+	ASSERT_RTNL();
+
 	/*
 	 *	Is it already up?
 	 */
@@ -1060,6 +1066,8 @@
  */
 int dev_close(struct net_device *dev)
 {
+	ASSERT_RTNL();
+
 	might_sleep();
 
 	if (!(dev->flags & IFF_UP))
@@ -4480,17 +4488,19 @@
 	rtnl_lock();
 	for_each_netdev_safe(net, dev, next) {
 		int err;
+		char fb_name[IFNAMSIZ];
 
 		/* Ignore unmoveable devices (i.e. loopback) */
 		if (dev->features & NETIF_F_NETNS_LOCAL)
 			continue;
 
 		/* Push remaing network devices to init_net */
-		err = dev_change_net_namespace(dev, &init_net, "dev%d");
+		snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
+		err = dev_change_net_namespace(dev, &init_net, fb_name);
 		if (err) {
-			printk(KERN_WARNING "%s: failed to move %s to init_net: %d\n",
+			printk(KERN_EMERG "%s: failed to move %s to init_net: %d\n",
 				__func__, dev->name, err);
-			unregister_netdevice(dev);
+			BUG();
 		}
 	}
 	rtnl_unlock();
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b04d643..8fb134d 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -419,7 +419,7 @@
 		return;
 
 	size = arp_hdr_len(skb->dev);
-	send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
+	send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev),
 			    LL_RESERVED_SPACE(np->dev));
 
 	if (!send_skb)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4fe605f..5c459f2 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -200,7 +200,9 @@
 		goto nodata;
 
 	/*
-	 * See comment in sk_buff definition, just before the 'tail' member
+	 * Only clear those fields we need to clear, not those that we will
+	 * actually initialise below. Hence, don't put any more fields after
+	 * the tail pointer in struct sk_buff!
 	 */
 	memset(skb, 0, offsetof(struct sk_buff, tail));
 	skb->truesize = size + sizeof(struct sk_buff);
diff --git a/net/core/sock.c b/net/core/sock.c
index fa76f04..88094cb 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -270,7 +270,7 @@
 	int err = 0;
 	int skb_len;
 
-	/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
+	/* Cast sk->rcvbuf to unsigned... It's pointless, but reduces
 	   number of warnings when compiling with -W --ANK
 	 */
 	if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 4a4f6ce..933a0ec 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -32,7 +32,7 @@
 
 	if (len > 3) {
 		DCCP_WARN("invalid length %d\n", len);
-		return 1;
+		return -EINVAL;
 	}
 	/* XXX add further sanity checks */
 
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 2f665a5..f50e88b 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -235,14 +235,14 @@
 	else
 		min_mtu -= 21;
 
-	if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= min_mtu) {
+	if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
 		if (!(dst_metric_locked(dst, RTAX_MTU))) {
 			dst->metrics[RTAX_MTU-1] = mtu;
 			dst_set_expires(dst, dn_rt_mtu_expires);
 		}
 		if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
 			u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
-			if (dst->metrics[RTAX_ADVMSS-1] > mss)
+			if (dst_metric(dst, RTAX_ADVMSS) > mss)
 				dst->metrics[RTAX_ADVMSS-1] = mss;
 		}
 	}
@@ -805,12 +805,12 @@
 		rt->u.dst.neighbour = n;
 	}
 
-	if (rt->u.dst.metrics[RTAX_MTU-1] == 0 ||
-	    rt->u.dst.metrics[RTAX_MTU-1] > rt->u.dst.dev->mtu)
+	if (dst_metric(&rt->u.dst, RTAX_MTU) == 0 ||
+	    dst_metric(&rt->u.dst, RTAX_MTU) > rt->u.dst.dev->mtu)
 		rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu;
 	mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->u.dst));
-	if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0 ||
-	    rt->u.dst.metrics[RTAX_ADVMSS-1] > mss)
+	if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0 ||
+	    dst_metric(&rt->u.dst, RTAX_ADVMSS) > mss)
 		rt->u.dst.metrics[RTAX_ADVMSS-1] = mss;
 	return 0;
 }
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 68d1544..7c9bb13 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -340,7 +340,7 @@
 
 		dev_hold(dev);
 
-		skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev),
+		skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
 					  msg->msg_flags & MSG_DONTWAIT, &err);
 		if (skb==NULL)
 			goto out_unlock;
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 68b72a7..418862f 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -570,7 +570,7 @@
 	 *	Allocate a buffer
 	 */
 
-	skb = alloc_skb(arp_hdr_len(dev) + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
+	skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
 	if (skb == NULL)
 		return NULL;
 
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 05afb57..2c0e457 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -338,7 +338,7 @@
 		return -ENOENT;
 
 	hash = cipso_v4_map_cache_hash(key, key_len);
-	bkt = hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
+	bkt = hash & (CIPSO_V4_CACHE_BUCKETS - 1);
 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
 	list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) {
 		if (entry->hash == hash &&
@@ -417,7 +417,7 @@
 	atomic_inc(&secattr->cache->refcount);
 	entry->lsm_data = secattr->cache;
 
-	bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
+	bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETS - 1);
 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
 	if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) {
 		list_add(&entry->list, &cipso_v4_cache[bkt].list);
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 6250f42..2769dc4 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -292,7 +292,7 @@
 	struct iphdr *pip;
 	struct igmpv3_report *pig;
 
-	skb = alloc_skb(size + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
+	skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
 	if (skb == NULL)
 		return NULL;
 
@@ -653,7 +653,7 @@
 		return -1;
 	}
 
-	skb=alloc_skb(IGMP_SIZE+LL_RESERVED_SPACE(dev), GFP_ATOMIC);
+	skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
 	if (skb == NULL) {
 		ip_rt_put(rt);
 		return -1;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 7b4bad6..ff77a4a 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -397,7 +397,7 @@
 	iph = ip_hdr(skb);
 
 	/*
-	 *	RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum.
+	 *	RFC1122: 3.2.1.2 MUST silently discard any IP frame that fails the checksum.
 	 *
 	 *	Is the datagram acceptable?
 	 *
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 89dee43..ed45037 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -710,14 +710,14 @@
 	struct net_device *dev = d->dev;
 	struct sk_buff *skb;
 	struct bootp_pkt *b;
-	int hh_len = LL_RESERVED_SPACE(dev);
 	struct iphdr *h;
 
 	/* Allocate packet */
-	skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
+	skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15,
+			GFP_KERNEL);
 	if (!skb)
 		return;
-	skb_reserve(skb, hh_len);
+	skb_reserve(skb, LL_RESERVED_SPACE(dev));
 	b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
 	memset(b, 0, sizeof(struct bootp_pkt));
 
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 11d7f75..fead049 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -322,7 +322,6 @@
 			unsigned int flags)
 {
 	struct inet_sock *inet = inet_sk(sk);
-	int hh_len;
 	struct iphdr *iph;
 	struct sk_buff *skb;
 	unsigned int iphlen;
@@ -336,13 +335,12 @@
 	if (flags&MSG_PROBE)
 		goto out;
 
-	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
-
-	skb = sock_alloc_send_skb(sk, length+hh_len+15,
-				  flags&MSG_DONTWAIT, &err);
+	skb = sock_alloc_send_skb(sk,
+				  length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
+				  flags & MSG_DONTWAIT, &err);
 	if (skb == NULL)
 		goto error;
-	skb_reserve(skb, hh_len);
+	skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
 
 	skb->priority = sk->sk_priority;
 	skb->mark = sk->sk_mark;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5e3685c..92f90ae 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1468,14 +1468,14 @@
 
 					/* BSD 4.2 compatibility hack :-( */
 					if (mtu == 0 &&
-					    old_mtu >= rth->u.dst.metrics[RTAX_MTU-1] &&
+					    old_mtu >= dst_metric(&rth->u.dst, RTAX_MTU) &&
 					    old_mtu >= 68 + (iph->ihl << 2))
 						old_mtu -= iph->ihl << 2;
 
 					mtu = guess_mtu(old_mtu);
 				}
-				if (mtu <= rth->u.dst.metrics[RTAX_MTU-1]) {
-					if (mtu < rth->u.dst.metrics[RTAX_MTU-1]) {
+				if (mtu <= dst_metric(&rth->u.dst, RTAX_MTU)) {
+					if (mtu < dst_metric(&rth->u.dst, RTAX_MTU)) {
 						dst_confirm(&rth->u.dst);
 						if (mtu < ip_rt_min_pmtu) {
 							mtu = ip_rt_min_pmtu;
@@ -1497,7 +1497,7 @@
 
 static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
 {
-	if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= 68 &&
+	if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= 68 &&
 	    !(dst_metric_locked(dst, RTAX_MTU))) {
 		if (mtu < ip_rt_min_pmtu) {
 			mtu = ip_rt_min_pmtu;
@@ -1613,7 +1613,7 @@
 		       sizeof(rt->u.dst.metrics));
 		if (fi->fib_mtu == 0) {
 			rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu;
-			if (rt->u.dst.metrics[RTAX_LOCK-1] & (1 << RTAX_MTU) &&
+			if (dst_metric_locked(&rt->u.dst, RTAX_MTU) &&
 			    rt->rt_gateway != rt->rt_dst &&
 			    rt->u.dst.dev->mtu > 576)
 				rt->u.dst.metrics[RTAX_MTU-1] = 576;
@@ -1624,14 +1624,14 @@
 	} else
 		rt->u.dst.metrics[RTAX_MTU-1]= rt->u.dst.dev->mtu;
 
-	if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0)
+	if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0)
 		rt->u.dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl;
-	if (rt->u.dst.metrics[RTAX_MTU-1] > IP_MAX_MTU)
+	if (dst_metric(&rt->u.dst, RTAX_MTU) > IP_MAX_MTU)
 		rt->u.dst.metrics[RTAX_MTU-1] = IP_MAX_MTU;
-	if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0)
+	if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0)
 		rt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->u.dst.dev->mtu - 40,
 				       ip_rt_min_advmss);
-	if (rt->u.dst.metrics[RTAX_ADVMSS-1] > 65535 - 40)
+	if (dst_metric(&rt->u.dst, RTAX_ADVMSS) > 65535 - 40)
 		rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535 - 40;
 
 #ifdef CONFIG_NET_CLS_ROUTE
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index eda4f4a..b54d9d3 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -66,6 +66,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/sysctl.h>
+#include <net/dst.h>
 #include <net/tcp.h>
 #include <net/inet_common.h>
 #include <linux/ipsec.h>
@@ -113,8 +114,6 @@
 #define FLAG_FORWARD_PROGRESS	(FLAG_ACKED|FLAG_DATA_SACKED)
 #define FLAG_ANY_PROGRESS	(FLAG_FORWARD_PROGRESS|FLAG_SND_UNA_ADVANCED)
 
-#define IsSackFrto() (sysctl_tcp_frto == 0x2)
-
 #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)
 #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
 
@@ -605,7 +604,7 @@
 	u32 rto_min = TCP_RTO_MIN;
 
 	if (dst && dst_metric_locked(dst, RTAX_RTO_MIN))
-		rto_min = dst->metrics[RTAX_RTO_MIN - 1];
+		rto_min = dst_metric(dst, RTAX_RTO_MIN);
 	return rto_min;
 }
 
@@ -769,7 +768,7 @@
 				dst->metrics[RTAX_RTTVAR - 1] = m;
 			else
 				dst->metrics[RTAX_RTTVAR-1] -=
-					(dst->metrics[RTAX_RTTVAR-1] - m)>>2;
+					(dst_metric(dst, RTAX_RTTVAR) - m)>>2;
 		}
 
 		if (tp->snd_ssthresh >= 0xFFFF) {
@@ -788,21 +787,21 @@
 				dst->metrics[RTAX_SSTHRESH-1] =
 					max(tp->snd_cwnd >> 1, tp->snd_ssthresh);
 			if (!dst_metric_locked(dst, RTAX_CWND))
-				dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_cwnd) >> 1;
+				dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_cwnd) >> 1;
 		} else {
 			/* Else slow start did not finish, cwnd is non-sense,
 			   ssthresh may be also invalid.
 			 */
 			if (!dst_metric_locked(dst, RTAX_CWND))
-				dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_ssthresh) >> 1;
-			if (dst->metrics[RTAX_SSTHRESH-1] &&
+				dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_ssthresh) >> 1;
+			if (dst_metric(dst, RTAX_SSTHRESH) &&
 			    !dst_metric_locked(dst, RTAX_SSTHRESH) &&
-			    tp->snd_ssthresh > dst->metrics[RTAX_SSTHRESH-1])
+			    tp->snd_ssthresh > dst_metric(dst, RTAX_SSTHRESH))
 				dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh;
 		}
 
 		if (!dst_metric_locked(dst, RTAX_REORDERING)) {
-			if (dst->metrics[RTAX_REORDERING-1] < tp->reordering &&
+			if (dst_metric(dst, RTAX_REORDERING) < tp->reordering &&
 			    tp->reordering != sysctl_tcp_reordering)
 				dst->metrics[RTAX_REORDERING-1] = tp->reordering;
 		}
@@ -1685,6 +1684,11 @@
 	tp->sacked_out = 0;
 }
 
+static int tcp_is_sackfrto(const struct tcp_sock *tp)
+{
+	return (sysctl_tcp_frto == 0x2) && !tcp_is_reno(tp);
+}
+
 /* F-RTO can only be used if TCP has never retransmitted anything other than
  * head (SACK enhanced variant from Appendix B of RFC4138 is more robust here)
  */
@@ -1701,7 +1705,7 @@
 	if (icsk->icsk_mtup.probe_size)
 		return 0;
 
-	if (IsSackFrto())
+	if (tcp_is_sackfrto(tp))
 		return 1;
 
 	/* Avoid expensive walking of rexmit queue if possible */
@@ -1791,7 +1795,7 @@
 	/* Earlier loss recovery underway (see RFC4138; Appendix B).
 	 * The last condition is necessary at least in tp->frto_counter case.
 	 */
-	if (IsSackFrto() && (tp->frto_counter ||
+	if (tcp_is_sackfrto(tp) && (tp->frto_counter ||
 	    ((1 << icsk->icsk_ca_state) & (TCPF_CA_Recovery|TCPF_CA_Loss))) &&
 	    after(tp->high_seq, tp->snd_una)) {
 		tp->frto_highmark = tp->high_seq;
@@ -1838,9 +1842,16 @@
 			TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
 		}
 
-		/* Don't lost mark skbs that were fwd transmitted after RTO */
-		if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) &&
-		    !after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) {
+		/* Marking forward transmissions that were made after RTO lost
+		 * can cause unnecessary retransmissions in some scenarios,
+		 * SACK blocks will mitigate that in some but not in all cases.
+		 * We used to not mark them but it was causing break-ups with
+		 * receivers that do only in-order receival.
+		 *
+		 * TODO: we could detect presence of such receiver and select
+		 * different behavior per flow.
+		 */
+		if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
 			TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
 			tp->lost_out += tcp_skb_pcount(skb);
 		}
@@ -1856,7 +1867,7 @@
 	tp->reordering = min_t(unsigned int, tp->reordering,
 			       sysctl_tcp_reordering);
 	tcp_set_ca_state(sk, TCP_CA_Loss);
-	tp->high_seq = tp->frto_highmark;
+	tp->high_seq = tp->snd_nxt;
 	TCP_ECN_queue_cwr(tp);
 
 	tcp_clear_retrans_hints_partial(tp);
@@ -2478,7 +2489,7 @@
 
 	tcp_verify_left_out(tp);
 
-	if (tp->retrans_out == 0)
+	if (!tp->frto_counter && tp->retrans_out == 0)
 		tp->retrans_stamp = 0;
 
 	if (flag & FLAG_ECE)
@@ -3123,7 +3134,7 @@
 		return 1;
 	}
 
-	if (!IsSackFrto() || tcp_is_reno(tp)) {
+	if (!tcp_is_sackfrto(tp)) {
 		/* RFC4138 shortcoming in step 2; should also have case c):
 		 * ACK isn't duplicate nor advances window, e.g., opposite dir
 		 * data, winupdate
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0af2e05..48cdce9 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -780,7 +780,7 @@
 		 *	Allocate buffer.
 		 */
 
-		if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
+		if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
 			NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
 			IP6_INC_STATS(ip6_dst_idev(skb->dst),
 				      IPSTATS_MIB_FRAGFAILS);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 54f91ef..fd632dd 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1411,7 +1411,7 @@
 		     IPV6_TLV_PADN, 0 };
 
 	/* we assume size > sizeof(ra) here */
-	skb = sock_alloc_send_skb(sk, size + LL_RESERVED_SPACE(dev), 1, &err);
+	skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err);
 
 	if (!skb)
 		return NULL;
@@ -1790,7 +1790,7 @@
 	payload_len = len + sizeof(ra);
 	full_len = sizeof(struct ipv6hdr) + payload_len;
 
-	skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
+	skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
 
 	if (skb == NULL) {
 		rcu_read_lock();
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 2c74885..a55fc05 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -479,7 +479,7 @@
 
 	skb = sock_alloc_send_skb(sk,
 				  (MAX_HEADER + sizeof(struct ipv6hdr) +
-				   len + LL_RESERVED_SPACE(dev)),
+				   len + LL_ALLOCATED_SPACE(dev)),
 				  1, &err);
 	if (!skb) {
 		ND_PRINTK0(KERN_ERR
@@ -1521,7 +1521,7 @@
 
 	buff = sock_alloc_send_skb(sk,
 				   (MAX_HEADER + sizeof(struct ipv6hdr) +
-				    len + LL_RESERVED_SPACE(dev)),
+				    len + LL_ALLOCATED_SPACE(dev)),
 				   1, &err);
 	if (buff == NULL) {
 		ND_PRINTK0(KERN_ERR
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 396f0ea..232e0dc 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -609,7 +609,6 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct ipv6hdr *iph;
 	struct sk_buff *skb;
-	unsigned int hh_len;
 	int err;
 
 	if (length > rt->u.dst.dev->mtu) {
@@ -619,13 +618,12 @@
 	if (flags&MSG_PROBE)
 		goto out;
 
-	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
-
-	skb = sock_alloc_send_skb(sk, length+hh_len+15,
-				  flags&MSG_DONTWAIT, &err);
+	skb = sock_alloc_send_skb(sk,
+				  length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
+				  flags & MSG_DONTWAIT, &err);
 	if (skb == NULL)
 		goto error;
-	skb_reserve(skb, hh_len);
+	skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
 
 	skb->priority = sk->sk_priority;
 	skb->mark = sk->sk_mark;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a493ad9..12bba08 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1243,11 +1243,11 @@
 		}
 	}
 
-	if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0)
+	if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0)
 		rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1;
-	if (!rt->u.dst.metrics[RTAX_MTU-1])
+	if (!dst_metric(&rt->u.dst, RTAX_MTU))
 		rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev);
-	if (!rt->u.dst.metrics[RTAX_ADVMSS-1])
+	if (!dst_metric(&rt->u.dst, RTAX_ADVMSS))
 		rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst));
 	rt->u.dst.dev = dev;
 	rt->rt6i_idev = idev;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 4b2f103..5a6fab9 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -596,9 +596,9 @@
 	}
 
 	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
-	kfree_skb(skb);
 	read_unlock(&ipip6_lock);
 out:
+	kfree_skb(skb);
 	return 0;
 }
 
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index bfacef8..a6f99b5 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -40,6 +40,8 @@
 
 #include <net/irda/discovery.h>
 
+#include <asm/unaligned.h>
+
 /*
  * Function irlmp_add_discovery (cachelog, discovery)
  *
@@ -87,7 +89,7 @@
 			 */
 			hashbin_remove_this(cachelog, (irda_queue_t *) node);
 			/* Check if hints bits are unchanged */
-			if(u16ho(node->data.hints) == u16ho(new->data.hints))
+			if (get_unaligned((__u16 *)node->data.hints) == get_unaligned((__u16 *)new->data.hints))
 				/* Set time of first discovery for this node */
 				new->firststamp = node->firststamp;
 			kfree(node);
@@ -281,9 +283,9 @@
 		/* Mask out the ones we don't want :
 		 * We want to match the discovery mask, and to get only
 		 * the most recent one (unless we want old ones) */
-		if ((u16ho(discovery->data.hints) & mask) &&
+		if ((get_unaligned((__u16 *)discovery->data.hints) & mask) &&
 		    ((old_entries) ||
-		     ((jiffies - discovery->firststamp) < j_timeout)) ) {
+		     ((jiffies - discovery->firststamp) < j_timeout))) {
 			/* Create buffer as needed.
 			 * As this function get called a lot and most time
 			 * we don't have anything to put in the log (we are
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 1f81f8e..7bf5b91 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -1062,7 +1062,8 @@
 		for(i = 0; i < number; i++) {
 			/* Check if we should notify client */
 			if ((client->expir_callback) &&
-			    (client->hint_mask.word & u16ho(expiries[i].hints)
+			    (client->hint_mask.word &
+			     get_unaligned((__u16 *)expiries[i].hints)
 			     & 0x7f7f) )
 				client->expir_callback(&(expiries[i]),
 						       EXPIRY_TIMEOUT,
@@ -1086,7 +1087,7 @@
 
 	IRDA_ASSERT(irlmp != NULL, return NULL;);
 
-	u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word;
+	put_unaligned(irlmp->hints.word, (__u16 *)irlmp->discovery_rsp.data.hints);
 
 	/*
 	 *  Set character set for device name (we use ASCII), and
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index 75497e5..cf9a4b5 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -10,6 +10,7 @@
 
 #include "irnet_irda.h"		/* Private header */
 #include <linux/seq_file.h>
+#include <asm/unaligned.h>
 
 /*
  * PPP disconnect work: we need to make sure we're in
@@ -1673,7 +1674,7 @@
   /* Notify the control channel */
   irnet_post_event(NULL, IRNET_DISCOVER,
 		   discovery->saddr, discovery->daddr, discovery->info,
-		   u16ho(discovery->hints));
+		   get_unaligned((__u16 *)discovery->hints));
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
@@ -1704,7 +1705,7 @@
   /* Notify the control channel */
   irnet_post_event(NULL, IRNET_EXPIRE,
 		   expiry->saddr, expiry->daddr, expiry->info,
-		   u16ho(expiry->hints));
+		   get_unaligned((__u16 *)expiry->hints));
 
   DEXIT(IRDA_OCB_TRACE, "\n");
 }
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 879e721..19efc3a 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -255,14 +255,23 @@
 void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
 {
 	char buf[50];
+	struct ieee80211_key *key;
 
 	if (!sdata->debugfsdir)
 		return;
 
-	sprintf(buf, "../keys/%d", sdata->default_key->debugfs.cnt);
-	sdata->debugfs.default_key =
-		debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
+	/* this is running under the key lock */
+
+	key = sdata->default_key;
+	if (key) {
+		sprintf(buf, "../keys/%d", key->debugfs.cnt);
+		sdata->debugfs.default_key =
+			debugfs_create_symlink("default_key",
+					       sdata->debugfsdir, buf);
+	} else
+		ieee80211_debugfs_key_remove_default(sdata);
 }
+
 void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
 {
 	if (!sdata)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 5a9a3c6..3c64e42 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -53,6 +53,15 @@
 	if (!ndev)
 		return -ENOMEM;
 
+	ndev->needed_headroom = local->tx_headroom +
+				4*6 /* four MAC addresses */
+				+ 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */
+				+ 6 /* mesh */
+				+ 8 /* rfc1042/bridge tunnel */
+				- ETH_HLEN /* ethernet hard_header_len */
+				+ IEEE80211_ENCRYPT_HEADROOM;
+	ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
+
 	ret = dev_alloc_name(ndev, ndev->name);
 	if (ret < 0)
 		goto fail;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 390df48..3601636 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1772,6 +1772,7 @@
 fail_rate:
 	ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
 	unregister_netdevice(local->mdev);
+	local->mdev = NULL;
 fail_dev:
 	rtnl_unlock();
 	sta_info_stop(local);
@@ -1779,8 +1780,10 @@
 	debugfs_hw_del(local);
 	destroy_workqueue(local->hw.workqueue);
 fail_workqueue:
-	ieee80211_if_free(local->mdev);
-	local->mdev = NULL;
+	if (local->mdev != NULL) {
+		ieee80211_if_free(local->mdev);
+		local->mdev = NULL;
+	}
 fail_mdev_alloc:
 	wiphy_unregister(local->hw.wiphy);
 	return result;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index f76bc26..697ef67 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -397,7 +397,7 @@
 	put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum);
 	sdata->u.sta.mesh_seqnum++;
 
-	return 5;
+	return 6;
 }
 
 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 2368973..7fa149e 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -120,7 +120,7 @@
 		*pos++ = WLAN_EID_PREP;
 		break;
 	default:
-		kfree(skb);
+		kfree_skb(skb);
 		return -ENOTSUPP;
 		break;
 	}
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 5845dc2..99c2d36 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -158,19 +158,25 @@
 	if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0)
 		return -ENOSPC;
 
-	read_lock(&pathtbl_resize_lock);
-
 	new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
 	if (!new_mpath) {
 		atomic_dec(&sdata->u.sta.mpaths);
 		err = -ENOMEM;
 		goto endadd2;
 	}
+	new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
+	if (!new_node) {
+		kfree(new_mpath);
+		atomic_dec(&sdata->u.sta.mpaths);
+		err = -ENOMEM;
+		goto endadd2;
+	}
+
+	read_lock(&pathtbl_resize_lock);
 	memcpy(new_mpath->dst, dst, ETH_ALEN);
 	new_mpath->dev = dev;
 	new_mpath->flags = 0;
 	skb_queue_head_init(&new_mpath->frame_queue);
-	new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
 	new_node->mpath = new_mpath;
 	new_mpath->timer.data = (unsigned long) new_mpath;
 	new_mpath->timer.function = mesh_path_timer;
@@ -202,7 +208,6 @@
 
 endadd:
 	spin_unlock(&mesh_paths->hashwlock[hash_idx]);
-endadd2:
 	read_unlock(&pathtbl_resize_lock);
 	if (!err && grow) {
 		struct mesh_table *oldtbl, *newtbl;
@@ -215,10 +220,12 @@
 			return -ENOMEM;
 		}
 		rcu_assign_pointer(mesh_paths, newtbl);
+		write_unlock(&pathtbl_resize_lock);
+
 		synchronize_rcu();
 		mesh_table_free(oldtbl, false);
-		write_unlock(&pathtbl_resize_lock);
 	}
+endadd2:
 	return err;
 }
 
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index dda30e98..7877d3b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -657,6 +657,26 @@
 	mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
 }
 
+static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
+				      struct ieee80211_supported_band *sband,
+				      u64 *rates)
+{
+	int i, j, count;
+	*rates = 0;
+	count = 0;
+	for (i = 0; i < bss->supp_rates_len; i++) {
+		int rate = (bss->supp_rates[i] & 0x7F) * 5;
+
+		for (j = 0; j < sband->n_bitrates; j++)
+			if (sband->bitrates[j].bitrate == rate) {
+				*rates |= BIT(j);
+				count++;
+				break;
+			}
+	}
+
+	return count;
+}
 
 static void ieee80211_send_assoc(struct net_device *dev,
 				 struct ieee80211_if_sta *ifsta)
@@ -665,11 +685,12 @@
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 	u8 *pos, *ies;
-	int i, len;
+	int i, len, count, rates_len, supp_rates_len;
 	u16 capab;
 	struct ieee80211_sta_bss *bss;
 	int wmm = 0;
 	struct ieee80211_supported_band *sband;
+	u64 rates = 0;
 
 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
 			    sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
@@ -731,24 +752,39 @@
 	*pos++ = ifsta->ssid_len;
 	memcpy(pos, ifsta->ssid, ifsta->ssid_len);
 
-	len = sband->n_bitrates;
-	if (len > 8)
-		len = 8;
-	pos = skb_put(skb, len + 2);
-	*pos++ = WLAN_EID_SUPP_RATES;
-	*pos++ = len;
-	for (i = 0; i < len; i++) {
-		int rate = sband->bitrates[i].bitrate;
-		*pos++ = (u8) (rate / 5);
-	}
+	/* all supported rates should be added here but some APs
+	 * (e.g. D-Link DAP 1353 in b-only mode) don't like that
+	 * Therefore only add rates the AP supports */
+	rates_len = ieee80211_compatible_rates(bss, sband, &rates);
+	supp_rates_len = rates_len;
+	if (supp_rates_len > 8)
+		supp_rates_len = 8;
 
-	if (sband->n_bitrates > len) {
-		pos = skb_put(skb, sband->n_bitrates - len + 2);
-		*pos++ = WLAN_EID_EXT_SUPP_RATES;
-		*pos++ = sband->n_bitrates - len;
-		for (i = len; i < sband->n_bitrates; i++) {
+	len = sband->n_bitrates;
+	pos = skb_put(skb, supp_rates_len + 2);
+	*pos++ = WLAN_EID_SUPP_RATES;
+	*pos++ = supp_rates_len;
+
+	count = 0;
+	for (i = 0; i < sband->n_bitrates; i++) {
+		if (BIT(i) & rates) {
 			int rate = sband->bitrates[i].bitrate;
 			*pos++ = (u8) (rate / 5);
+			if (++count == 8)
+				break;
+		}
+	}
+
+	if (count == 8) {
+		pos = skb_put(skb, rates_len - count + 2);
+		*pos++ = WLAN_EID_EXT_SUPP_RATES;
+		*pos++ = rates_len - count;
+
+		for (i++; i < sband->n_bitrates; i++) {
+			if (BIT(i) & rates) {
+				int rate = sband->bitrates[i].bitrate;
+				*pos++ = (u8) (rate / 5);
+			}
 		}
 	}
 
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index ae75d41..ff5c380f 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -85,7 +85,7 @@
 	struct rc_pid_sta_info *sinfo = inode->i_private;
 	struct rc_pid_event_buffer *events = &sinfo->events;
 	struct rc_pid_events_file_info *file_info;
-	unsigned int status;
+	unsigned long status;
 
 	/* Allocate a state struct */
 	file_info = kmalloc(sizeof(*file_info), GFP_KERNEL);
@@ -135,7 +135,7 @@
 	char pb[RC_PID_PRINT_BUF_SIZE];
 	int ret;
 	int p;
-	unsigned int status;
+	unsigned long status;
 
 	/* Check if there is something to read. */
 	if (events->next_entry == file_info->next_entry) {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 1159a43a..fa68305 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1372,11 +1372,11 @@
 		if (is_multicast_ether_addr(skb->data)) {
 			if (*mesh_ttl > 0) {
 				xmit_skb = skb_copy(skb, GFP_ATOMIC);
-				if (!xmit_skb && net_ratelimit())
+				if (xmit_skb)
+					xmit_skb->pkt_type = PACKET_OTHERHOST;
+				else if (net_ratelimit())
 					printk(KERN_DEBUG "%s: failed to clone "
 					       "multicast frame\n", dev->name);
-				else
-					xmit_skb->pkt_type = PACKET_OTHERHOST;
 			} else
 				IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta,
 							     dropped_frames_ttl);
@@ -1462,7 +1462,7 @@
 		padding = ((4 - subframe_len) & 0x3);
 		/* the last MSDU has no padding */
 		if (subframe_len > remaining) {
-			printk(KERN_DEBUG "%s: wrong buffer size", dev->name);
+			printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name);
 			return RX_DROP_UNUSABLE;
 		}
 
@@ -1485,7 +1485,7 @@
 			eth = (struct ethhdr *) skb_pull(skb, ntohs(len) +
 							padding);
 			if (!eth) {
-				printk(KERN_DEBUG "%s: wrong buffer size ",
+				printk(KERN_DEBUG "%s: wrong buffer size\n",
 				       dev->name);
 				dev_kfree_skb(frame);
 				return RX_DROP_UNUSABLE;
@@ -2019,7 +2019,7 @@
 		if (!skb_new) {
 			if (net_ratelimit())
 				printk(KERN_DEBUG "%s: failed to copy "
-				       "multicast frame for %s",
+				       "multicast frame for %s\n",
 				       wiphy_name(local->hw.wiphy),
 				       prev->dev->name);
 			continue;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4c25fd5..aecec2a 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1565,13 +1565,13 @@
 	 * be cloned. This could happen, e.g., with Linux bridge code passing
 	 * us broadcast frames. */
 
-	if (head_need > 0 || skb_cloned(skb)) {
+	if (head_need > 0 || skb_header_cloned(skb)) {
 #if 0
 		printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes "
 		       "of headroom\n", dev->name, head_need);
 #endif
 
-		if (skb_cloned(skb))
+		if (skb_header_cloned(skb))
 			I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
 		else
 			I802_DEBUG_INC(local->tx_expand_skb_head);
@@ -1904,6 +1904,7 @@
 			control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
 		control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
 		control->flags |= IEEE80211_TXCTL_NO_ACK;
+		control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
 		control->retry_limit = 1;
 		control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
 	}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index cc9f715..24a465c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -153,15 +153,15 @@
 	/* 7.1.3.5a.2 */
 	switch (ae) {
 	case 0:
-		return 5;
+		return 6;
 	case 1:
-		return 11;
+		return 12;
 	case 2:
-		return 17;
+		return 18;
 	case 3:
-		return 23;
+		return 24;
 	default:
-		return 5;
+		return 6;
 	}
 }
 
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 8ffff27..c87baf4c 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -379,7 +379,8 @@
 						 qd->handle);
 		if (!q->queues[i]) {
 			q->queues[i] = &noop_qdisc;
-			printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i);
+			printk(KERN_ERR "%s child qdisc %i creation failed\n",
+			       dev->name, i);
 		}
 	}
 
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c1fc0f1..aa8d80c 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -90,6 +90,7 @@
 	tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
 	depends on EXPERIMENTAL && NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
+	default IP_DCCP
 	help
 	  With this option enabled, the layer 3 independent connection
 	  tracking code will be able to do state tracking on DCCP connections.
@@ -104,6 +105,7 @@
 	tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
 	depends on EXPERIMENTAL && NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
+	default IP_SCTP
 	help
 	  With this option enabled, the layer 3 independent connection
 	  tracking code will be able to do state tracking on SCTP connections.
@@ -532,6 +534,7 @@
 	tristate '"dccp" protocol match support'
 	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
+	default IP_DCCP
 	help
 	  With this option enabled, you will be able to use the iptables
 	  `dccp' match in order to match on DCCP source/destination ports
@@ -725,6 +728,7 @@
 	tristate  '"sctp" protocol match support (EXPERIMENTAL)'
 	depends on NETFILTER_XTABLES && EXPERIMENTAL
 	depends on NETFILTER_ADVANCED
+	default IP_SCTP
 	help
 	  With this option enabled, you will be able to use the 
 	  `sctp' match in order to match on SCTP source/destination ports
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 16774ec..0edefcf 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -472,6 +472,9 @@
 		goto nla_put_failure;
 	nla_nest_end(skb, nest_parms);
 
+	if (ctnetlink_dump_id(skb, ct) < 0)
+		goto nla_put_failure;
+
 	if (events & IPCT_DESTROY) {
 		if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
 		    ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 9f49000..2f9bbc0 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -870,6 +870,7 @@
 {
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+	struct nf_conn_help *help = nfct_help(ct);
 	unsigned int matchoff, matchlen;
 	unsigned int mediaoff, medialen;
 	unsigned int sdpoff;
@@ -959,6 +960,9 @@
 	if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
 		ret = nf_nat_sdp_session(skb, dptr, sdpoff, datalen, &rtp_addr);
 
+	if (ret == NF_ACCEPT && i > 0)
+		help->help.ct_sip_info.invite_cseq = cseq;
+
 	return ret;
 }
 static int process_invite_response(struct sk_buff *skb,
@@ -967,14 +971,14 @@
 {
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+	struct nf_conn_help *help = nfct_help(ct);
 
 	if ((code >= 100 && code <= 199) ||
 	    (code >= 200 && code <= 299))
 		return process_sdp(skb, dptr, datalen, cseq);
-	else {
+	else if (help->help.ct_sip_info.invite_cseq == cseq)
 		flush_expectations(ct, true);
-		return NF_ACCEPT;
-	}
+	return NF_ACCEPT;
 }
 
 static int process_update_response(struct sk_buff *skb,
@@ -983,14 +987,14 @@
 {
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+	struct nf_conn_help *help = nfct_help(ct);
 
 	if ((code >= 100 && code <= 199) ||
 	    (code >= 200 && code <= 299))
 		return process_sdp(skb, dptr, datalen, cseq);
-	else {
+	else if (help->help.ct_sip_info.invite_cseq == cseq)
 		flush_expectations(ct, true);
-		return NF_ACCEPT;
-	}
+	return NF_ACCEPT;
 }
 
 static int process_prack_response(struct sk_buff *skb,
@@ -999,14 +1003,14 @@
 {
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+	struct nf_conn_help *help = nfct_help(ct);
 
 	if ((code >= 100 && code <= 199) ||
 	    (code >= 200 && code <= 299))
 		return process_sdp(skb, dptr, datalen, cseq);
-	else {
+	else if (help->help.ct_sip_info.invite_cseq == cseq)
 		flush_expectations(ct, true);
-		return NF_ACCEPT;
-	}
+	return NF_ACCEPT;
 }
 
 static int process_bye_request(struct sk_buff *skb,
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index 500528d..c63e933 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -179,3 +179,5 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>");
 MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
+MODULE_ALIAS("ipt_iprange");
+MODULE_ALIAS("ip6t_iprange");
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2507024..2cee87d 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -743,7 +743,7 @@
 	if (len > dev->mtu+reserve)
 		goto out_unlock;
 
-	skb = sock_alloc_send_skb(sk, len + LL_RESERVED_SPACE(dev),
+	skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
 				msg->msg_flags & MSG_DONTWAIT, &err);
 	if (skb==NULL)
 		goto out_unlock;
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 64b2d13..1d421d0 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -6,7 +6,7 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  *
- * Authors:	Jamal Hadi Salim (2005)
+ * Authors:	Jamal Hadi Salim (2005-8)
  *
  */
 
@@ -34,6 +34,7 @@
 	.lock	=	&simp_lock,
 };
 
+#define SIMP_MAX_DATA	32
 static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
 {
 	struct tcf_defact *d = a->priv;
@@ -69,23 +70,28 @@
 	return ret;
 }
 
-static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
+static int alloc_defdata(struct tcf_defact *d, char *defdata)
 {
-	d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL);
+	d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL);
 	if (unlikely(!d->tcfd_defdata))
 		return -ENOMEM;
-	d->tcfd_datalen = datalen;
+
 	return 0;
 }
 
-static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
+static void reset_policy(struct tcf_defact *d, char *defdata,
+			 struct tc_defact *p)
 {
-	kfree(d->tcfd_defdata);
-	return alloc_defdata(d, datalen, defdata);
+	spin_lock_bh(&d->tcf_lock);
+	d->tcf_action = p->action;
+	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
+	strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+	spin_unlock_bh(&d->tcf_lock);
 }
 
 static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
 	[TCA_DEF_PARMS]	= { .len = sizeof(struct tc_defact) },
+	[TCA_DEF_DATA]	= { .type = NLA_STRING, .len = SIMP_MAX_DATA },
 };
 
 static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
@@ -95,28 +101,24 @@
 	struct tc_defact *parm;
 	struct tcf_defact *d;
 	struct tcf_common *pc;
-	void *defdata;
-	u32 datalen = 0;
+	char *defdata;
 	int ret = 0, err;
 
 	if (nla == NULL)
 		return -EINVAL;
 
-	err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL);
+	err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
 	if (err < 0)
 		return err;
 
 	if (tb[TCA_DEF_PARMS] == NULL)
 		return -EINVAL;
 
-	parm = nla_data(tb[TCA_DEF_PARMS]);
-	defdata = nla_data(tb[TCA_DEF_DATA]);
-	if (defdata == NULL)
+	if (tb[TCA_DEF_DATA] == NULL)
 		return -EINVAL;
 
-	datalen = nla_len(tb[TCA_DEF_DATA]);
-	if (datalen == 0)
-		return -EINVAL;
+	parm = nla_data(tb[TCA_DEF_PARMS]);
+	defdata = nla_data(tb[TCA_DEF_DATA]);
 
 	pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info);
 	if (!pc) {
@@ -126,11 +128,12 @@
 			return -ENOMEM;
 
 		d = to_defact(pc);
-		ret = alloc_defdata(d, datalen, defdata);
+		ret = alloc_defdata(d, defdata);
 		if (ret < 0) {
 			kfree(pc);
 			return ret;
 		}
+		d->tcf_action = parm->action;
 		ret = ACT_P_CREATED;
 	} else {
 		d = to_defact(pc);
@@ -138,13 +141,9 @@
 			tcf_simp_release(d, bind);
 			return -EEXIST;
 		}
-		realloc_defdata(d, datalen, defdata);
+		reset_policy(d, defdata, parm);
 	}
 
-	spin_lock_bh(&d->tcf_lock);
-	d->tcf_action = parm->action;
-	spin_unlock_bh(&d->tcf_lock);
-
 	if (ret == ACT_P_CREATED)
 		tcf_hash_insert(pc, &simp_hash_info);
 	return ret;
@@ -172,7 +171,7 @@
 	opt.bindcnt = d->tcf_bindcnt - bind;
 	opt.action = d->tcf_action;
 	NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
-	NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata);
+	NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
 	t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
 	t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 66148cc..5bc1ed4 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1197,12 +1197,16 @@
 	return 1;
 }
 
-static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q)
+static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
+			       struct Qdisc *new_q)
 {
 	struct htb_class *parent = cl->parent;
 
 	BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity);
 
+	if (parent->cmode != HTB_CAN_SEND)
+		htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level);
+
 	parent->level = 0;
 	memset(&parent->un.inner, 0, sizeof(parent->un.inner));
 	INIT_LIST_HEAD(&parent->un.leaf.drop_list);
@@ -1300,7 +1304,7 @@
 		htb_deactivate(q, cl);
 
 	if (last_child)
-		htb_parent_to_leaf(cl, new_q);
+		htb_parent_to_leaf(q, cl, new_q);
 
 	if (--cl->refcnt == 0)
 		htb_destroy_class(sch, cl);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 81b6064..bbc7107 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2418,7 +2418,8 @@
 				break;
 
 			case SCTP_PARAM_IPV6_ADDRESS:
-				asoc->peer.ipv6_address = 1;
+				if (PF_INET6 == asoc->base.sk->sk_family)
+					asoc->peer.ipv6_address = 1;
 				break;
 
 			case SCTP_PARAM_HOST_NAME_ADDRESS:
@@ -2829,6 +2830,19 @@
 	addr_param = (union sctp_addr_param *)
 			((void *)asconf_param + sizeof(sctp_addip_param_t));
 
+	switch (addr_param->v4.param_hdr.type) {
+	case SCTP_PARAM_IPV6_ADDRESS:
+		if (!asoc->peer.ipv6_address)
+			return SCTP_ERROR_INV_PARAM;
+		break;
+	case SCTP_PARAM_IPV4_ADDRESS:
+		if (!asoc->peer.ipv4_address)
+			return SCTP_ERROR_INV_PARAM;
+		break;
+	default:
+		return SCTP_ERROR_INV_PARAM;
+	}
+
 	af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
 	if (unlikely(!af))
 		return SCTP_ERROR_INV_PARAM;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index d74c2d2..01c7e31 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -18,7 +18,6 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/sched.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 0d783bc..bd78d17 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -303,15 +303,14 @@
 /*
  * TIPC message buffer code
  *
- * TIPC message buffer headroom reserves space for a link-level header
- * (in case the message is sent off-node),
- * while ensuring TIPC header is word aligned for quicker access
+ * TIPC message buffer headroom reserves space for the worst-case
+ * link-level device header (in case the message is sent off-node).
  *
- * The largest header currently supported is 18 bytes, which is used when
- * the standard 14 byte Ethernet header has 4 added bytes for VLAN info
+ * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields
+ *       are word aligned for quicker access
  */
 
-#define BUF_HEADROOM 20u
+#define BUF_HEADROOM LL_MAX_HEADER
 
 struct tipc_skb_cb {
 	void *handle;
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 09cd9c0..3f964db 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -25,11 +25,11 @@
 	struct dst_entry *dst = skb->dst;
 	int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
 		- skb_headroom(skb);
+	int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
 
-	if (nhead > 0)
-		return pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
+	if (nhead > 0 || ntail > 0)
+		return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
 
-	/* Check tail too... */
 	return 0;
 }
 
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index a78a8d0..379bcb0 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -5,8 +5,8 @@
 
 
 config SND_PCSP
-	tristate "Internal PC speaker support"
-	depends on X86_PC && HIGH_RES_TIMERS
+	tristate "PC-Speaker support"
+	depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS
 	depends on INPUT
 	depends on SND
 	select SND_PCM
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 5920351..54a1f90 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -194,6 +194,7 @@
 	spin_unlock_irq(&chip->substream_lock);
 }
 
+#ifdef CONFIG_PM
 static int pcsp_suspend(struct platform_device *dev, pm_message_t state)
 {
 	struct snd_pcsp *chip = platform_get_drvdata(dev);
@@ -201,6 +202,9 @@
 	snd_pcm_suspend_all(chip->pcm);
 	return 0;
 }
+#else
+#define pcsp_suspend NULL
+#endif	/* CONFIG_PM */
 
 static void pcsp_shutdown(struct platform_device *dev)
 {
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index dfe670f..eb9bc36 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -67,7 +67,7 @@
 		return 1;
 	
 	mem = ioremap(base, 128);
-	if(mem == 0UL)
+	if (!mem)
 		return 1;
 	map = readw(mem + 0x18);	/* Read the SMI enables */
 	iounmap(mem);
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 581debf..7e47421 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -515,19 +515,16 @@
 config SND_FM801_TEA575X_BOOL
 	bool "ForteMedia FM801 + TEA5757 tuner"
 	depends on SND_FM801
+	depends on VIDEO_V4L1=y || VIDEO_V4L1=SND_FM801
 	help
 	  Say Y here to include support for soundcards based on the ForteMedia
 	  FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
 	  Forte SF256-PCS-02) into the snd-fm801 driver.
 
-	  This will enable support for the old V4L1 API.
-
 config SND_FM801_TEA575X
 	tristate
 	depends on SND_FM801_TEA575X_BOOL
 	default SND_FM801
-	select VIDEO_V4L1
-	select VIDEO_DEV
 
 config SND_HDA_INTEL
 	tristate "Intel HD Audio"
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 39198e5..2da8981 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -3446,6 +3446,7 @@
 int patch_vt1617a(struct snd_ac97 * ac97)
 {
 	int err = 0;
+	int val;
 
 	/* we choose to not fail out at this point, but we tell the
 	   caller when we return */
@@ -3456,7 +3457,13 @@
 	/* bring analog power consumption to normal by turning off the
 	 * headphone amplifier, like WinXP driver for EPIA SP
 	 */
-	snd_ac97_write_cache(ac97, 0x5c, 0x20);
+	/* We need to check the bit before writing it.
+	 * On some (many?) hardwares, setting bit actually clears it!
+	 */
+	val = snd_ac97_read(ac97, 0x5c);
+	if (!(val & 0x20))
+		snd_ac97_write_cache(ac97, 0x5c, 0x20);
+
 	ac97->ext_id |= AC97_EI_SPDIF;	/* force the detection of spdif */
 	ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
 	ac97->build_ops = &patch_vt1616_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index d9783a4..6d4df45 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -11902,7 +11902,10 @@
 					      hda_nid_t nid,
 					      int pin_type, int dac_idx)
 {
-	alc_set_pin_output(codec, nid, pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+			    pin_type);
+	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+			    AMP_OUT_UNMUTE);
 }
 
 static void alc861_auto_init_multi_out(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b3a15d6..393f7fd 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4289,6 +4289,8 @@
 	{ .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
 	{ .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
 	{ .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
+	{ .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x },
+	{ .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x },
  	/* The following does not take into account .id=0x83847661 when subsys =
  	 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
  	 * currently not fully supported.
diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c
index 67c88e3..ccac6bd 100644
--- a/sound/soc/at91/at91-pcm.c
+++ b/sound/soc/at91/at91-pcm.c
@@ -103,7 +103,8 @@
 		if (prtd->period_ptr >= prtd->dma_buffer_end) {
 			prtd->period_ptr = prtd->dma_buffer;
 		}
-		at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr);
+		at91_ssc_write(params->ssc_base + params->pdc->xnpr,
+			       prtd->period_ptr);
 		at91_ssc_write(params->ssc_base + params->pdc->xncr,
 				prtd->period_size / params->pdc_xfer_size);
 	}
@@ -191,10 +192,12 @@
 		at91_ssc_write(params->ssc_base + AT91_SSC_IER,
 			params->mask->ssc_endx | params->mask->ssc_endbuf);
 
-		at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
+		at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR,
+			params->mask->pdc_enable);
 
-		DBG("sr=%lx imr=%lx\n", at91_ssc_read(params->ssc_base + AT91_SSC_SR),
-					at91_ssc_read(params->ssc_base + AT91_SSC_IER));
+		DBG("sr=%lx imr=%lx\n",
+		    at91_ssc_read(params->ssc_base + AT91_SSC_SR),
+		    at91_ssc_read(params->ssc_base + AT91_SSC_IMR));
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
index f642d2d..bc35d00 100644
--- a/sound/soc/at91/at91-ssc.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -590,7 +590,7 @@
 			printk(KERN_WARNING "at91-ssc: request_irq failure\n");
 
 			DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
-			at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
+			at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
 			return ret;
 		}
 
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 630684f..09b1661 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -539,8 +539,8 @@
 	{"HPRCOM", NULL, "Right HP Com"},
 
 	/* Mono Output */
-	{"MONOLOUT", NULL, "Mono Out"},
-	{"MONOLOUT", NULL, "Mono Out"},
+	{"MONO_LOUT", NULL, "Mono Out"},
+	{"MONO_LOUT", NULL, "Mono Out"},
 
 	/* Left Input */
 	{"Left Line1L Mux", "single-ended", "LINE1L"},
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index b2a11b0..f588545 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -416,7 +416,7 @@
 			 * to put data into its FIFO.  Without it, ALSA starts
 			 * to complain about overruns.
 			 */
-			msleep(1);
+			mdelay(1);
 		}
 		break;
 
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 83b1eb4..6533563 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -188,8 +188,8 @@
 static const char *spk_function[] = {"Off", "On"};
 static const char *jack_function[] = {"Off", "Headphone"};
 static const struct soc_enum n810_enum[] = {
-	SOC_ENUM_SINGLE_EXT(2, spk_function),
-	SOC_ENUM_SINGLE_EXT(3, jack_function),
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function),
 };
 
 static const struct snd_kcontrol_new aic33_n810_controls[] = {
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 4ebcd6a..1ed6afd 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -224,6 +224,7 @@
 		iismod |= S3C2410_IISMOD_SLAVE;
 		break;
 	case SND_SOC_DAIFMT_CBS_CFS:
+		iismod &= ~S3C2410_IISMOD_SLAVE;
 		break;
 	default:
 		return -EINVAL;
@@ -234,6 +235,7 @@
 		iismod |= S3C2410_IISMOD_MSB;
 		break;
 	case SND_SOC_DAIFMT_I2S:
+		iismod &= ~S3C2410_IISMOD_MSB;
 		break;
 	default:
 		return -EINVAL;
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index 6c70a81..7806ae6 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -171,7 +171,7 @@
 		ret = s3c2410_dma_request(prtd->params->channel,
 					  prtd->params->client, NULL);
 
-		if (ret) {
+		if (ret < 0) {
 			DBG(KERN_ERR "failed to get dma channel\n");
 			return ret;
 		}
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 478369b..b343818 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -341,8 +341,12 @@
 	case MIDI_CTL_SOFT_PEDAL:
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
 		/* FIXME: this is an emulation */
-		snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
+		if (chan->control[type] >= 64)
+			snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
 				     EMUX_FX_FLAG_ADD);
+		else
+			snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
+				     EMUX_FX_FLAG_OFF);
 #endif
 		break;