Merge master.kernel.org:/home/rmk/linux-2.6-serial
diff --git a/CREDITS b/CREDITS
index 8e577ce..6957ef4 100644
--- a/CREDITS
+++ b/CREDITS
@@ -3101,7 +3101,7 @@
 S: Australia
 
 N: Stephen Smalley
-E: sds@epoch.ncsc.mil
+E: sds@tycho.nsa.gov
 D: portions of the Linux Security Module (LSM) framework and security modules
 
 N: Chris Smith
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 4d4897c..b730d76 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -162,3 +162,12 @@
 When:	January 2007
 Why:	Is replaced by pci_register_driver(pci_driver).
 Who:	Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de>
+
+---------------------------
+
+What:	I2C interface of the it87 driver
+When:	January 2007
+Why:	The ISA interface is faster and should be always available. The I2C
+	probing is also known to cause trouble in at least one case (see
+	bug #5889.)
+Who:	Jean Delvare <khali@linux-fr.org>
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f
new file mode 100644
index 0000000..28c5b7d
--- /dev/null
+++ b/Documentation/hwmon/f71805f
@@ -0,0 +1,105 @@
+Kernel driver f71805f
+=====================
+
+Supported chips:
+  * Fintek F71805F/FG
+    Prefix: 'f71805f'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Provided by Fintek on request
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+Thanks to Denis Kieft from Barracuda Networks for the donation of a
+test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and
+for providing initial documentation.
+
+Thanks to Kris Chen from Fintek for answering technical questions and
+providing additional documentation.
+
+Thanks to Chris Lin from Jetway for providing wiring schematics and
+anwsering technical questions.
+
+
+Description
+-----------
+
+The Fintek F71805F/FG Super I/O chip includes complete hardware monitoring
+capabilities. It can monitor up to 9 voltages (counting its own power
+source), 3 fans and 3 temperature sensors.
+
+This chip also has fan controlling features, using either DC or PWM, in
+three different modes (one manual, two automatic). The driver doesn't
+support these features yet.
+
+The driver assumes that no more than one chip is present, which seems
+reasonable.
+
+
+Voltage Monitoring
+------------------
+
+Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported
+range is thus from 0 to 2.040 V. Voltage values outside of this range
+need external resistors. An exception is in0, which is used to monitor
+the chip's own power source (+3.3V), and is divided internally by a
+factor 2.
+
+The two LSB of the voltage limit registers are not used (always 0), so
+you can only set the limits in steps of 32 mV (before scaling).
+
+The wirings and resistor values suggested by Fintek are as follow:
+
+        pin                                           expected
+        name    use           R1      R2     divider  raw val.
+
+in0     VCC     VCC3.3V     int.    int.        2.00    1.65 V
+in1     VIN1    VTT1.2V      10K       -        1.00    1.20 V
+in2     VIN2    VRAM        100K    100K        2.00   ~1.25 V (1)
+in3     VIN3    VCHIPSET     47K    100K        1.47    2.24 V (2)
+in4     VIN4    VCC5V       200K     47K        5.25    0.95 V
+in5     VIN5    +12V        200K     20K       11.00    1.05 V
+in6     VIN6    VCC1.5V      10K       -        1.00    1.50 V
+in7     VIN7    VCORE        10K       -        1.00   ~1.40 V (1)
+in8     VIN8    VSB5V       200K     47K        1.00    0.95 V
+
+(1) Depends on your hardware setup.
+(2) Obviously not correct, swapping R1 and R2 would make more sense.
+
+These values can be used as hints at best, as motherboard manufacturers
+are free to use a completely different setup. As a matter of fact, the
+Jetway K8M8MS uses a significantly different setup. You will have to
+find out documentation about your own motherboard, and edit sensors.conf
+accordingly.
+
+Each voltage measured has associated low and high limits, each of which
+triggers an alarm when crossed.
+
+
+Fan Monitoring
+--------------
+
+Fan rotation speeds are reported as 12-bit values from a gated clock
+signal. Speeds down to 366 RPM can be measured. There is no theoretical
+high limit, but values over 6000 RPM seem to cause problem. The effective
+resolution is much lower than you would expect, the step between different
+register values being 10 rather than 1.
+
+The chip assumes 2 pulse-per-revolution fans.
+
+An alarm is triggered if the rotation speed drops below a programmable
+limit or is too low to be measured.
+
+
+Temperature Monitoring
+----------------------
+
+Temperatures are reported in degrees Celsius. Each temperature measured
+has a high limit, those crossing triggers an alarm. There is an associated
+hysteresis value, below which the temperature has to drop before the
+alarm is cleared.
+
+All temperature channels are external, there is no embedded temperature
+sensor. Each channel can be used for connecting either a thermal diode
+or a thermistor. The driver reports the currently selected mode, but
+doesn't allow changing it. In theory, the BIOS should have configured
+everything properly.
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index 7f42e44..9555be1 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -9,7 +9,7 @@
                http://www.ite.com.tw/
   * IT8712F
     Prefix: 'it8712'
-    Addresses scanned: I2C 0x28 - 0x2f
+    Addresses scanned: I2C 0x2d
                        from Super I/O config space (8 I/O ports)
     Datasheet: Publicly available at the ITE website
                http://www.ite.com.tw/
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index 764cdc5..a0d0ab2 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -179,11 +179,12 @@
 ****************
 
 temp[1-3]_type	Sensor type selection.
-		Integers 1, 2, 3 or thermistor Beta value (3435)
+		Integers 1 to 4 or thermistor Beta value (typically 3435)
 		Read/Write.
 		1: PII/Celeron Diode
 		2: 3904 transistor
 		3: thermal diode
+		4: thermistor (default/unknown Beta)
 		Not all types are supported by all chips
 
 temp[1-4]_max	Temperature max value.
@@ -261,6 +262,21 @@
 		of individual bits.
 		Bits are defined in kernel/include/sensors.h.
 
+alarms_in	Alarm bitmask relative to in (voltage) channels
+		Read only
+		A '1' bit means an alarm, LSB corresponds to in0 and so on
+		Prefered to 'alarms' for newer chips
+
+alarms_fan	Alarm bitmask relative to fan channels
+		Read only
+		A '1' bit means an alarm, LSB corresponds to fan1 and so on
+		Prefered to 'alarms' for newer chips
+
+alarms_temp	Alarm bitmask relative to temp (temperature) channels
+		Read only
+		A '1' bit means an alarm, LSB corresponds to temp1 and so on
+		Prefered to 'alarms' for newer chips
+
 beep_enable	Beep/interrupt enable
 		0 to disable.
 		1 to enable.
diff --git a/Documentation/i2c/busses/i2c-sis69x b/Documentation/i2c/busses/i2c-sis96x
similarity index 98%
rename from Documentation/i2c/busses/i2c-sis69x
rename to Documentation/i2c/busses/i2c-sis96x
index b88953d..00a009b 100644
--- a/Documentation/i2c/busses/i2c-sis69x
+++ b/Documentation/i2c/busses/i2c-sis96x
@@ -7,7 +7,7 @@
     Any combination of these host bridges:
 	645, 645DX (aka 646), 648, 650, 651, 655, 735, 745, 746
     and these south bridges:
-    	961, 962, 963(L) 
+    	961, 962, 963(L)
 
 Author: Mark M. Hoffman <mhoffman@lightlink.com>
 
@@ -29,7 +29,7 @@
 
 or perhaps this...
 
-00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645 
+00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645
 00:02.0 ISA bridge: Silicon Integrated Systems [SiS]: Unknown device 0961
 00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016
 
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 1284498..54e5f9b 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -880,6 +880,10 @@
     - device_type : Should be "soc"
     - ranges : Should be defined as specified in 1) to describe the
       translation of SOC addresses for memory mapped SOC registers.
+    - bus-frequency: Contains the bus frequency for the SOC node.
+      Typically, the value of this field is filled in by the boot
+      loader. 
+
 
   Recommended properties:
 
@@ -919,6 +923,7 @@
 		device_type = "soc";
 		ranges = <00000000 e0000000 00100000>
 		reg = <e0000000 00003000>;
+		bus-frequency = <0>;
 	}
 
 
@@ -1170,6 +1175,8 @@
 
 	mdio@24520 {
 		reg = <24520 20>;
+		device_type = "mdio"; 
+		compatible = "gianfar";
 
 		ethernet-phy@0 {
 			......
@@ -1317,6 +1324,7 @@
 		device_type = "soc";
 		ranges = <00000000 e0000000 00100000>
 		reg = <e0000000 00003000>;
+		bus-frequency = <0>;
 
 		mdio@24520 {
 			reg = <24520 20>;
diff --git a/Documentation/spi/butterfly b/Documentation/spi/butterfly
index a2e8c8d..9927af7a 100644
--- a/Documentation/spi/butterfly
+++ b/Documentation/spi/butterfly
@@ -12,13 +12,20 @@
 directly to the Butterfly.  Or (if you have the parts and skills) you
 can come up with something fancier, providing ciruit protection to the
 Butterfly and the printer port, or with a better power supply than two
-signal pins from the printer port.
+signal pins from the printer port.  Or for that matter, you can use
+similar cables to talk to many AVR boards, even a breadboard.
+
+This is more powerful than "ISP programming" cables since it lets kernel
+SPI protocol drivers interact with the AVR, and could even let the AVR
+issue interrupts to them.  Later, your protocol driver should work
+easily with a "real SPI controller", instead of this bitbanger.
 
 
 The first cable connections will hook Linux up to one SPI bus, with the
 AVR and a DataFlash chip; and to the AVR reset line.  This is all you
 need to reflash the firmware, and the pins are the standard Atmel "ISP"
-connector pins (used also on non-Butterfly AVR boards).
+connector pins (used also on non-Butterfly AVR boards).  On the parport
+side this is like "sp12" programming cables.
 
 	Signal	  Butterfly	  Parport (DB-25)
 	------	  ---------	  ---------------
@@ -40,10 +47,14 @@
 	SELECT	= J400.PB0/nSS	= pin 17/C3,nSELECT
 	GND	= J400.GND	= pin 24/GND
 
-The "USI" controller, using J405, can be used for a second SPI bus.  That
-would let you talk to the AVR over SPI, running firmware that makes it act
-as an SPI slave, while letting either Linux or the AVR use the DataFlash.
-There are plenty of spare parport pins to wire this one up, such as:
+Or you could flash firmware making the AVR into an SPI slave (keeping the
+DataFlash in reset) and tweak the spi_butterfly driver to make it bind to
+the driver for your custom SPI-based protocol.
+
+The "USI" controller, using J405, can also be used for a second SPI bus.
+That would let you talk to the AVR using custom SPI-with-USI firmware,
+while letting either Linux or the AVR use the DataFlash.  There are plenty
+of spare parport pins to wire this one up, such as:
 
 	Signal	  Butterfly	  Parport (DB-25)
 	------	  ---------	  ---------------
diff --git a/Documentation/unshare.txt b/Documentation/unshare.txt
new file mode 100644
index 0000000..90a5e9e
--- /dev/null
+++ b/Documentation/unshare.txt
@@ -0,0 +1,295 @@
+
+unshare system call:
+--------------------
+This document describes the new system call, unshare. The document
+provides an overview of the feature, why it is needed, how it can
+be used, its interface specification, design, implementation and
+how it can be tested.
+
+Change Log:
+-----------
+version 0.1  Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006
+
+Contents:
+---------
+	1) Overview
+	2) Benefits
+	3) Cost
+	4) Requirements
+	5) Functional Specification
+	6) High Level Design
+	7) Low Level Design
+	8) Test Specification
+	9) Future Work
+
+1) Overview
+-----------
+Most legacy operating system kernels support an abstraction of threads
+as multiple execution contexts within a process. These kernels provide
+special resources and mechanisms to maintain these "threads". The Linux
+kernel, in a clever and simple manner, does not make distinction
+between processes and "threads". The kernel allows processes to share
+resources and thus they can achieve legacy "threads" behavior without
+requiring additional data structures and mechanisms in the kernel. The
+power of implementing threads in this manner comes not only from
+its simplicity but also from allowing application programmers to work
+outside the confinement of all-or-nothing shared resources of legacy
+threads. On Linux, at the time of thread creation using the clone system
+call, applications can selectively choose which resources to share
+between threads.
+
+unshare system call adds a primitive to the Linux thread model that
+allows threads to selectively 'unshare' any resources that were being
+shared at the time of their creation. unshare was conceptualized by
+Al Viro in the August of 2000, on the Linux-Kernel mailing list, as part
+of the discussion on POSIX threads on Linux.  unshare augments the
+usefulness of Linux threads for applications that would like to control
+shared resources without creating a new process. unshare is a natural
+addition to the set of available primitives on Linux that implement
+the concept of process/thread as a virtual machine.
+
+2) Benefits
+-----------
+unshare would be useful to large application frameworks such as PAM
+where creating a new process to control sharing/unsharing of process
+resources is not possible. Since namespaces are shared by default
+when creating a new process using fork or clone, unshare can benefit
+even non-threaded applications if they have a need to disassociate
+from default shared namespace. The following lists two use-cases
+where unshare can be used.
+
+2.1 Per-security context namespaces
+-----------------------------------
+unshare can be used to implement polyinstantiated directories using
+the kernel's per-process namespace mechanism. Polyinstantiated directories,
+such as per-user and/or per-security context instance of /tmp, /var/tmp or
+per-security context instance of a user's home directory, isolate user
+processes when working with these directories. Using unshare, a PAM
+module can easily setup a private namespace for a user at login.
+Polyinstantiated directories are required for Common Criteria certification
+with Labeled System Protection Profile, however, with the availability
+of shared-tree feature in the Linux kernel, even regular Linux systems
+can benefit from setting up private namespaces at login and
+polyinstantiating /tmp, /var/tmp and other directories deemed
+appropriate by system administrators.
+
+2.2 unsharing of virtual memory and/or open files
+-------------------------------------------------
+Consider a client/server application where the server is processing
+client requests by creating processes that share resources such as
+virtual memory and open files. Without unshare, the server has to
+decide what needs to be shared at the time of creating the process
+which services the request. unshare allows the server an ability to
+disassociate parts of the context during the servicing of the
+request. For large and complex middleware application frameworks, this
+ability to unshare after the process was created can be very
+useful.
+
+3) Cost
+-------
+In order to not duplicate code and to handle the fact that unshare
+works on an active task (as opposed to clone/fork working on a newly
+allocated inactive task) unshare had to make minor reorganizational
+changes to copy_* functions utilized by clone/fork system call.
+There is a cost associated with altering existing, well tested and
+stable code to implement a new feature that may not get exercised
+extensively in the beginning. However, with proper design and code
+review of the changes and creation of an unshare test for the LTP
+the benefits of this new feature can exceed its cost.
+
+4) Requirements
+---------------
+unshare reverses sharing that was done using clone(2) system call,
+so unshare should have a similar interface as clone(2). That is,
+since flags in clone(int flags, void *stack) specifies what should
+be shared, similar flags in unshare(int flags) should specify
+what should be unshared. Unfortunately, this may appear to invert
+the meaning of the flags from the way they are used in clone(2).
+However, there was no easy solution that was less confusing and that
+allowed incremental context unsharing in future without an ABI change.
+
+unshare interface should accommodate possible future addition of
+new context flags without requiring a rebuild of old applications.
+If and when new context flags are added, unshare design should allow
+incremental unsharing of those resources on an as needed basis.
+
+5) Functional Specification
+---------------------------
+NAME
+	unshare - disassociate parts of the process execution context
+
+SYNOPSIS
+	#include <sched.h>
+
+	int unshare(int flags);
+
+DESCRIPTION
+	unshare allows a process to disassociate parts of its execution
+	context that are currently being shared with other processes. Part
+	of execution context, such as the namespace, is shared by default
+	when a new process is created using fork(2), while other parts,
+	such as the virtual memory, open file descriptors, etc, may be
+	shared by explicit request to share them when creating a process
+	using clone(2).
+
+	The main use of unshare is to allow a process to control its
+	shared execution context without creating a new process.
+
+	The flags argument specifies one or bitwise-or'ed of several of
+	the following constants.
+
+	CLONE_FS
+		If CLONE_FS is set, file system information of the caller
+		is disassociated from the shared file system information.
+
+	CLONE_FILES
+		If CLONE_FILES is set, the file descriptor table of the
+		caller is disassociated from the shared file descriptor
+		table.
+
+	CLONE_NEWNS
+		If CLONE_NEWNS is set, the namespace of the caller is
+		disassociated from the shared namespace.
+
+	CLONE_VM
+		If CLONE_VM is set, the virtual memory of the caller is
+		disassociated from the shared virtual memory.
+
+RETURN VALUE
+	On success, zero returned. On failure, -1 is returned and errno is
+
+ERRORS
+	EPERM	CLONE_NEWNS was specified by a non-root process (process
+		without CAP_SYS_ADMIN).
+
+	ENOMEM	Cannot allocate sufficient memory to copy parts of caller's
+		context that need to be unshared.
+
+	EINVAL	Invalid flag was specified as an argument.
+
+CONFORMING TO
+	The unshare() call is Linux-specific and  should  not be used
+	in programs intended to be portable.
+
+SEE ALSO
+	clone(2), fork(2)
+
+6) High Level Design
+--------------------
+Depending on the flags argument, the unshare system call allocates
+appropriate process context structures, populates it with values from
+the current shared version, associates newly duplicated structures
+with the current task structure and releases corresponding shared
+versions. Helper functions of clone (copy_*) could not be used
+directly by unshare because of the following two reasons.
+  1) clone operates on a newly allocated not-yet-active task
+     structure, where as unshare operates on the current active
+     task. Therefore unshare has to take appropriate task_lock()
+     before associating newly duplicated context structures
+  2) unshare has to allocate and duplicate all context structures
+     that are being unshared, before associating them with the
+     current task and releasing older shared structures. Failure
+     do so will create race conditions and/or oops when trying
+     to backout due to an error. Consider the case of unsharing
+     both virtual memory and namespace. After successfully unsharing
+     vm, if the system call encounters an error while allocating
+     new namespace structure, the error return code will have to
+     reverse the unsharing of vm. As part of the reversal the
+     system call will have to go back to older, shared, vm
+     structure, which may not exist anymore.
+
+Therefore code from copy_* functions that allocated and duplicated
+current context structure was moved into new dup_* functions. Now,
+copy_* functions call dup_* functions to allocate and duplicate
+appropriate context structures and then associate them with the
+task structure that is being constructed. unshare system call on
+the other hand performs the following:
+  1) Check flags to force missing, but implied, flags
+  2) For each context structure, call the corresponding unshare
+     helper function to allocate and duplicate a new context
+     structure, if the appropriate bit is set in the flags argument.
+  3) If there is no error in allocation and duplication and there
+     are new context structures then lock the current task structure,
+     associate new context structures with the current task structure,
+     and release the lock on the current task structure.
+  4) Appropriately release older, shared, context structures.
+
+7) Low Level Design
+-------------------
+Implementation of unshare can be grouped in the following 4 different
+items:
+  a) Reorganization of existing copy_* functions
+  b) unshare system call service function
+  c) unshare helper functions for each different process context
+  d) Registration of system call number for different architectures
+
+  7.1) Reorganization of copy_* functions
+       Each copy function such as copy_mm, copy_namespace, copy_files,
+       etc, had roughly two components. The first component allocated
+       and duplicated the appropriate structure and the second component
+       linked it to the task structure passed in as an argument to the copy
+       function. The first component was split into its own function.
+       These dup_* functions allocated and duplicated the appropriate
+       context structure. The reorganized copy_* functions invoked
+       their corresponding dup_* functions and then linked the newly
+       duplicated structures to the task structure with which the
+       copy function was called.
+
+  7.2) unshare system call service function
+       * Check flags
+	 Force implied flags. If CLONE_THREAD is set force CLONE_VM.
+	 If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is
+	 set and signals are also being shared, force CLONE_THREAD. If
+	 CLONE_NEWNS is set, force CLONE_FS.
+       * For each context flag, invoke the corresponding unshare_*
+	 helper routine with flags passed into the system call and a
+	 reference to pointer pointing the new unshared structure
+       * If any new structures are created by unshare_* helper
+	 functions, take the task_lock() on the current task,
+	 modify appropriate context pointers, and release the
+         task lock.
+       * For all newly unshared structures, release the corresponding
+         older, shared, structures.
+
+  7.3) unshare_* helper functions
+       For unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND,
+       and CLONE_THREAD, return -EINVAL since they are not implemented yet.
+       For others, check the flag value to see if the unsharing is
+       required for that structure. If it is, invoke the corresponding
+       dup_* function to allocate and duplicate the structure and return
+       a pointer to it.
+
+  7.4) Appropriately modify architecture specific code to register the
+       the new system call.
+
+8) Test Specification
+---------------------
+The test for unshare should test the following:
+  1) Valid flags: Test to check that clone flags for signal and
+	signal handlers, for which unsharing is not implemented
+	yet, return -EINVAL.
+  2) Missing/implied flags: Test to make sure that if unsharing
+	namespace without specifying unsharing of filesystem, correctly
+	unshares both namespace and filesystem information.
+  3) For each of the four (namespace, filesystem, files and vm)
+	supported unsharing, verify that the system call correctly
+	unshares the appropriate structure. Verify that unsharing
+	them individually as well as in combination with each
+	other works as expected.
+  4) Concurrent execution: Use shared memory segments and futex on
+	an address in the shm segment to synchronize execution of
+	about 10 threads. Have a couple of threads execute execve,
+	a couple _exit and the rest unshare with different combination
+	of flags. Verify that unsharing is performed as expected and
+	that there are no oops or hangs.
+
+9) Future Work
+--------------
+The current implementation of unshare does not allow unsharing of
+signals and signal handlers. Signals are complex to begin with and
+to unshare signals and/or signal handlers of a currently running
+process is even more complex. If in the future there is a specific
+need to allow unsharing of signals and/or signal handlers, it can
+be incrementally added to unshare without affecting legacy
+applications using unshare.
+
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 56e194f..8bea3fb 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -42,4 +42,4 @@
  41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)  [0070:9800,0070:9802]
  42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025]
  43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
- 44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50]
+ 44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50,18ac:db54]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index cb3a59b..8a35259 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -1,7 +1,7 @@
   0 -> UNKNOWN/GENERIC
   1 -> Proteus Pro [philips reference design]   [1131:2001,1131:2001]
   2 -> LifeView FlyVIDEO3000                    [5168:0138,4e42:0138]
-  3 -> LifeView FlyVIDEO2000                    [5168:0138]
+  3 -> LifeView/Typhoon FlyVIDEO2000            [5168:0138,4e42:0138]
   4 -> EMPRESS                                  [1131:6752]
   5 -> SKNet Monster TV                         [1131:4e85]
   6 -> Tevion MD 9717
@@ -53,12 +53,12 @@
  52 -> AverMedia AverTV/305                     [1461:2108]
  53 -> ASUS TV-FM 7135                          [1043:4845]
  54 -> LifeView FlyTV Platinum FM               [5168:0214,1489:0214]
- 55 -> LifeView FlyDVB-T DUO                    [5168:0502,5168:0306]
+ 55 -> LifeView FlyDVB-T DUO                    [5168:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
  58 -> ADS Tech Instant TV (saa7135)            [1421:0350,1421:0351,1421:0370,1421:1370]
  59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
- 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
+ 60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus    [5168:0502,4e42:0502]
  61 -> Philips TOUGH DVB-T reference design     [1131:2004]
  62 -> Compro VideoMate TV Gold+II
  63 -> Kworld Xpert TV PVR7134
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index 9c5fc15..153740f 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -40,6 +40,18 @@
    no_timer_check Don't check the IO-APIC timer. This can work around
 		 problems with incorrect timer initialization on some boards.
 
+   apicmaintimer Run time keeping from the local APIC timer instead
+                 of using the PIT/HPET interrupt for this. This is useful
+                 when the PIT/HPET interrupts are unreliable.
+
+   noapicmaintimer  Don't do time keeping using the APIC timer.
+		 Useful when this option was auto selected, but doesn't work.
+
+   apicpmtimer
+		 Do APIC timer calibration using the pmtimer. Implies
+		 apicmaintimer. Useful when your PIT timer is totally
+		 broken.
+
 Early Console
 
    syntax: earlyprintk=vga
diff --git a/MAINTAINERS b/MAINTAINERS
index b6cbac5..b22db52 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -540,7 +540,8 @@
 
 BTTV VIDEO4LINUX DRIVER
 P:	Mauro Carvalho Chehab
-M:	mchehab@brturbo.com.br
+M:	mchehab@infradead.org
+M:	v4l-dvb-maintainer@linuxtv.org
 L:	video4linux-list@redhat.com
 W:	http://linuxtv.org
 T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
@@ -837,11 +838,12 @@
 
 DVB SUBSYSTEM AND DRIVERS
 P:	LinuxTV.org Project
-M: 	linux-dvb-maintainer@linuxtv.org
+M:	mchehab@infradead.org
+M:	v4l-dvb-maintainer@linuxtv.org
 L: 	linux-dvb@linuxtv.org (subscription required)
 W:	http://linuxtv.org/
 T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
-S:	Supported
+S:	Maintained
 
 EATA-DMA SCSI DRIVER
 P:	Michael Neuffer
@@ -929,6 +931,12 @@
 L:	ext3-users@redhat.com
 S:	Maintained
 
+F71805F HARDWARE MONITORING DRIVER
+P:	Jean Delvare
+M:	khali@linux-fr.org
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+
 FARSYNC SYNCHRONOUS DRIVER
 P:	Kevin Curtis
 M:	kevin.curtis@farsite.co.uk
@@ -2298,7 +2306,7 @@
 
 SELINUX SECURITY MODULE
 P:	Stephen Smalley
-M:	sds@epoch.ncsc.mil
+M:	sds@tycho.nsa.gov
 P:	James Morris
 M:	jmorris@namei.org
 L:	linux-kernel@vger.kernel.org (kernel issues)
@@ -2956,7 +2964,8 @@
 
 VIDEO FOR LINUX
 P:	Mauro Carvalho Chehab
-M:	mchehab@brturbo.com.br
+M:	mchehab@infradead.org
+M:	v4l-dvb-maintainer@linuxtv.org
 L:	video4linux-list@redhat.com
 W:	http://linuxtv.org
 T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
diff --git a/Makefile b/Makefile
index cd5b619..a1158d1 100644
--- a/Makefile
+++ b/Makefile
@@ -442,7 +442,7 @@
 config %config: scripts_basic outputmakefile FORCE
 	$(Q)mkdir -p include/linux
 	$(Q)$(MAKE) $(build)=scripts/kconfig $@
-	$(Q)$(MAKE) .kernelrelease
+	$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease
 
 else
 # ===========================================================================
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 4b87352..02c2db0 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -73,9 +73,6 @@
 
 EXPORT_SYMBOL(cpu_online_map);
 
-/* cpus reported in the hwrpb */
-static unsigned long hwrpb_cpu_present_mask __initdata = 0;
-
 int smp_num_probed;		/* Internal processor count */
 int smp_num_cpus = 1;		/* Number that came online.  */
 
@@ -442,7 +439,7 @@
 			if ((cpu->flags & 0x1cc) == 0x1cc) {
 				smp_num_probed++;
 				/* Assume here that "whami" == index */
-				hwrpb_cpu_present_mask |= (1UL << i);
+				cpu_set(i, cpu_possible_map);
 				cpu->pal_revision = boot_cpu_palrev;
 			}
 
@@ -453,12 +450,12 @@
 		}
 	} else {
 		smp_num_probed = 1;
-		hwrpb_cpu_present_mask = (1UL << boot_cpuid);
+		cpu_set(boot_cpuid, cpu_possible_map);
 	}
 	cpu_present_mask = cpumask_of_cpu(boot_cpuid);
 
 	printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
-	       smp_num_probed, hwrpb_cpu_present_mask);
+	       smp_num_probed, cpu_possible_map.bits[0]);
 }
 
 /*
@@ -467,8 +464,6 @@
 void __init
 smp_prepare_cpus(unsigned int max_cpus)
 {
-	int cpu_count, i;
-
 	/* Take care of some initial bookkeeping.  */
 	memset(ipi_data, 0, sizeof(ipi_data));
 
@@ -486,19 +481,7 @@
 
 	printk(KERN_INFO "SMP starting up secondaries.\n");
 
-	cpu_count = 1;
-	for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) {
-		if (i == boot_cpuid)
-			continue;
-
-		if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
-			continue;
-
-		cpu_set(i, cpu_possible_map);
-		cpu_count++;
-	}
-
-	smp_num_cpus = cpu_count;
+	smp_num_cpus = smp_num_probed;
 }
 
 void __devinit
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5959e36..15dc1a0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -10,9 +10,9 @@
 	default y
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
-	  licensed by ARM ltd and targeted at embedded applications and
+	  licensed by ARM Ltd and targeted at embedded applications and
 	  handhelds such as the Compaq IPAQ.  ARM-based PCs are no longer
-	  manufactured, but  legacy ARM-based PC hardware remains popular in
+	  manufactured, but legacy ARM-based PC hardware remains popular in
 	  Europe.  There is an ARM Linux project with a web page at
 	  <http://www.arm.linux.org.uk/>.
 
@@ -69,6 +69,9 @@
 config FIQ
 	bool
 
+config ARCH_MTD_XIP
+	bool
+
 source "init/Kconfig"
 
 menu "System Type"
@@ -81,45 +84,62 @@
 	bool "Cirrus-CL-PS7500FE"
 	select TIMER_ACORN
 	select ISA
+	help
+	  Support for the Cirrus Logic PS7500FE system-on-a-chip.
 
 config ARCH_CLPS711X
 	bool "CLPS711x/EP721x-based"
+	help
+	  Support for Cirrus Logic 711x/721x based boards.
 
 config ARCH_CO285
 	bool "Co-EBSA285"
 	select FOOTBRIDGE
 	select FOOTBRIDGE_ADDIN
+	help
+	  Support for Intel's EBSA285 companion chip.
 
 config ARCH_EBSA110
 	bool "EBSA-110"
 	select ISA
 	help
 	  This is an evaluation board for the StrongARM processor available
-	  from Digital. It has limited hardware on-board, including an onboard
+	  from Digital. It has limited hardware on-board, including an
 	  Ethernet interface, two PCMCIA sockets, two serial ports and a
 	  parallel port.
 
 config ARCH_FOOTBRIDGE
 	bool "FootBridge"
 	select FOOTBRIDGE
+	help
+	  Support for systems based on the DC21285 companion chip
+	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
 config ARCH_INTEGRATOR
 	bool "Integrator"
 	select ARM_AMBA
 	select ICST525
+	help
+	  Support for ARM's Integrator platform.
 
 config ARCH_IOP3XX
 	bool "IOP3xx-based"
 	select PCI
+	help
+	  Support for Intel's IOP3XX (XScale) family of processors.
 
 config ARCH_IXP4XX
 	bool "IXP4xx-based"
 	select DMABOUNCE
 	select PCI
+	help
+	  Support for Intel's IXP4XX (XScale) family of processors.
 
 config ARCH_IXP2000
 	bool "IXP2400/2800-based"
 	select PCI
+	help
+	  Support for Intel's IXP2400/2800 (XScale) family of processors.
 
 config ARCH_L7200
 	bool "LinkUp-L7200"
@@ -136,6 +156,9 @@
 
 config ARCH_PXA
 	bool "PXA2xx-based"
+	select ARCH_MTD_XIP
+	help
+	  Support for Intel's PXA2XX processor line.
 
 config ARCH_RPC
 	bool "RiscPC"
@@ -152,19 +175,25 @@
 	bool "SA1100-based"
 	select ISA
 	select ARCH_DISCONTIGMEM_ENABLE
+	select ARCH_MTD_XIP
+	help
+	  Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
 	bool "Samsung S3C2410"
 	help
 	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
 	  BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
-	  the Samsung SMDK2410 development board (and derviatives).
+	  the Samsung SMDK2410 development board (and derivatives).
 
 config ARCH_SHARK
 	bool "Shark"
 	select ISA
 	select ISA_DMA
 	select PCI
+	help
+	  Support for the StrongARM based Digital DNARD machine, also known
+	  as "Shark" (<http://www.shark-linux.de/shark.html>).
 
 config ARCH_LH7A40X
 	bool "Sharp LH7A40X"
@@ -176,6 +205,8 @@
 
 config ARCH_OMAP
 	bool "TI OMAP"
+	help
+	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
 config ARCH_VERSATILE
 	bool "Versatile"
@@ -194,6 +225,8 @@
 
 config ARCH_IMX
 	bool "IMX"
+	help
+	  Support for Motorola's i.MX family of processors (MX1, MXL).
 
 config ARCH_H720X
 	bool "Hynix-HMS720x-based"
@@ -210,8 +243,8 @@
 config ARCH_AT91RM9200
 	bool "AT91RM9200"
 	help
-	  Say Y here if you intend to run this kernel on an AT91RM9200-based
-	  board.
+	  Say Y here if you intend to run this kernel on an Atmel
+	  AT91RM9200-based board.
 
 endchoice
 
@@ -417,8 +450,8 @@
 	  To use this you need GCC version 4.0.0 or later.
 
 config OABI_COMPAT
-	bool "Allow old ABI binaries to run with this kernel"
-	depends on AEABI
+	bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
+	depends on AEABI && EXPERIMENTAL
 	default y
 	help
 	  This option preserves the old syscall interface along with the
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig
index 9592e39..5fdaf3c 100644
--- a/arch/arm/configs/enp2611_defconfig
+++ b/arch/arm/configs/enp2611_defconfig
@@ -171,7 +171,7 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
index d9d6bb8..c67fc44 100644
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -172,7 +172,7 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
index 2dc9d49..60d66e8 100644
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -172,7 +172,7 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
index ea8f4b4..f54f3dc 100644
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -172,7 +172,7 @@
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware ixdp2x01_clock=50000000"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 1964ccd..6695b07 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,11 +1,10 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Sun Nov 13 17:41:24 2005
+# Linux kernel version: 2.6.16-rc2
+# Mon Feb  6 11:17:23 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 
@@ -28,27 +27,31 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -102,6 +105,7 @@
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
 
 #
 # S3C24XX Implementations
@@ -160,7 +164,6 @@
 # Bus support
 #
 CONFIG_ISA=y
-CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -172,6 +175,7 @@
 #
 # CONFIG_PREEMPT is not set
 # CONFIG_NO_IDLE_HZ is not set
+# CONFIG_AEABI is not set
 # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -214,6 +218,8 @@
 # Power management options
 #
 CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
 CONFIG_APM=y
 
 #
@@ -259,6 +265,11 @@
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -276,7 +287,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -300,6 +310,11 @@
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
@@ -412,8 +427,6 @@
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -502,7 +515,6 @@
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_SMC91X is not set
 CONFIG_DM9000=y
@@ -607,11 +619,11 @@
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
 # CONFIG_DIGIEPCA is not set
-# CONFIG_ESPSERIAL is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -625,6 +637,7 @@
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -687,6 +700,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
@@ -731,6 +745,12 @@
 # CONFIG_I2C_DEBUG_CHIP is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
@@ -863,6 +883,7 @@
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 CONFIG_INOTIFY=y
@@ -897,6 +918,7 @@
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -965,6 +987,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -1020,12 +1043,13 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1034,6 +1058,7 @@
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_WAITQ is not set
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index d058e7c..8c3035d 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -291,21 +291,21 @@
 		CALL(sys_mq_getsetattr)
 /* 280 */	CALL(sys_waitid)
 		CALL(sys_socket)
-		CALL(sys_bind)
-		CALL(sys_connect)
+		CALL(ABI(sys_bind, sys_oabi_bind))
+		CALL(ABI(sys_connect, sys_oabi_connect))
 		CALL(sys_listen)
 /* 285 */	CALL(sys_accept)
 		CALL(sys_getsockname)
 		CALL(sys_getpeername)
 		CALL(sys_socketpair)
 		CALL(sys_send)
-/* 290 */	CALL(sys_sendto)
+/* 290 */	CALL(ABI(sys_sendto, sys_oabi_sendto))
 		CALL(sys_recv)
 		CALL(sys_recvfrom)
 		CALL(sys_shutdown)
 		CALL(sys_setsockopt)
 /* 295 */	CALL(sys_getsockopt)
-		CALL(sys_sendmsg)
+		CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
 		CALL(sys_recvmsg)
 		CALL(ABI(sys_semop, sys_oabi_semop))
 		CALL(sys_semget)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index d401d90..964cd71 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -333,10 +333,14 @@
 					@ from the exception stack
 
 #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#ifndef CONFIG_MMU
+#warning "NPTL on non MMU needs fixing"
+#else
 	@ make sure our user space atomic helper is aborted
 	cmp	r2, #TASK_SIZE
 	bichs	r3, r3, #PSR_Z_BIT
 #endif
+#endif
 
 	@
 	@ We are now ready to fill in the remaining blanks on the stack:
@@ -705,7 +709,12 @@
  * The C flag is also set if *ptr was changed to allow for assembly
  * optimization in the calling code.
  *
- * Note: this routine already includes memory barriers as needed.
+ * Notes:
+ *
+ *    - This routine already includes memory barriers as needed.
+ *
+ *    - A failure might be transient, i.e. it is possible, although unlikely,
+ *      that "failure" be returned even if *ptr == oldval.
  *
  * For example, a user space atomic_add implementation could look like this:
  *
@@ -756,12 +765,18 @@
 	 * exception happening just after the str instruction which would
 	 * clear the Z flag although the exchange was done.
 	 */
+#ifdef CONFIG_MMU
 	teq	ip, ip			@ set Z flag
 	ldr	ip, [r2]		@ load current val
 	add	r3, r2, #1		@ prepare store ptr
 	teqeq	ip, r0			@ compare with oldval if still allowed
 	streq	r1, [r3, #-1]!		@ store newval if still allowed
 	subs	r0, r2, r3		@ if r2 == r3 the str occured
+#else
+#warning "NPTL on non MMU needs fixing"
+	mov	r0, #-1
+	adds	r0, r0, #0
+#endif
 	mov	pc, lr
 
 #else
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index eafa8e5..9d4b764 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -59,6 +59,16 @@
  *   struct sembuf loses its padding with EABI.  Since arrays of them are
  *   used they have to be copyed to remove the padding. Compatibility wrappers
  *   provided below.
+ *
+ * sys_bind:
+ * sys_connect:
+ * sys_sendmsg:
+ * sys_sendto:
+ *
+ *   struct sockaddr_un loses its padding with EABI.  Since the size of the
+ *   structure is used as a validation test in unix_mkname(), we need to
+ *   change the length argument to 110 whenever it is 112.  Compatibility
+ *   wrappers provided below.
  */
 
 #include <linux/syscalls.h>
@@ -67,6 +77,7 @@
 #include <linux/fcntl.h>
 #include <linux/eventpoll.h>
 #include <linux/sem.h>
+#include <linux/socket.h>
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
 
@@ -337,3 +348,63 @@
 		return sys_ipc(call, first, second, third, ptr, fifth);
 	}
 }
+
+asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen)
+{
+	sa_family_t sa_family;
+	if (addrlen == 112 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+			addrlen = 110;
+	return sys_bind(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen)
+{
+	sa_family_t sa_family;
+	if (addrlen == 112 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+			addrlen = 110;
+	return sys_connect(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
+				size_t len, unsigned flags,
+				struct sockaddr __user *addr,
+				int addrlen)
+{
+	sa_family_t sa_family;
+	if (addrlen == 112 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+			addrlen = 110;
+	return sys_sendto(fd, buff, len, flags, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+{
+	struct sockaddr __user *addr;
+	int msg_namelen;
+	sa_family_t sa_family;
+	if (msg &&
+	    get_user(msg_namelen, &msg->msg_namelen) == 0 &&
+	    msg_namelen == 112 &&
+	    get_user(addr, &msg->msg_name) == 0 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+	{
+		/*
+		 * HACK ALERT: there is a limit to how much backward bending
+		 * we should do for what is actually a transitional
+		 * compatibility layer.  This already has known flaws with
+		 * a few ioctls that we don't intend to fix.  Therefore
+		 * consider this blatent hack as another one... and take care
+		 * to run for cover.  In most cases it will "just work fine".
+		 * If it doesn't, well, tough.
+		 */
+		put_user(110, &msg->msg_namelen);
+	}
+	return sys_sendmsg(fd, msg, flags);
+}
+
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index 0793dcf..0e2b641 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -24,6 +24,8 @@
 
 config ARCH_CLEP7312
 	bool "CLEP7312"
+	help
+	  Boards based on the Cirrus Logic 7212/7312 chips.
 
 config ARCH_EDB7211
 	bool "EDB7211"
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index 9e5a13b..52fac89 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -106,6 +106,7 @@
 {
 	ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
 	ixp2000_pci_preinit();
+	pcibios_setup("firmware");
 }
 
 static inline int enp2611_pci_valid_device(struct pci_bus *bus,
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index 7c78240..0910127 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -68,6 +68,7 @@
 {
 	ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
 	ixp2000_pci_preinit();
+	pcibios_setup("firmware");
 }
 
 int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys)
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 10f0660..150519f 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -212,6 +212,7 @@
 {
 	ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000);
 	ixp2000_pci_preinit();
+	pcibios_setup("firmware");
 }
 
 #define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
@@ -299,7 +300,9 @@
 
 int __init ixdp2x01_pci_init(void)
 {
-	pci_common_init(&ixdp2x01_pci);
+	if (machine_is_ixdp2401() || machine_is_ixdp2801())
+		pci_common_init(&ixdp2x01_pci);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index bdc20b5..a177e78 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -30,6 +30,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 }
 
@@ -104,7 +105,7 @@
 
 static void __init omap_generic_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 9533c36..89f0cc7 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -128,6 +128,7 @@
 
 static void __init h2_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 	h2_init_smc91x();
@@ -194,7 +195,7 @@
 
 static void __init h2_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_H2, "TI-H2")
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index d665efc..d9f3862 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -203,6 +203,7 @@
 
 void h3_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 	h3_init_smc91x();
@@ -210,7 +211,7 @@
 
 static void __init h3_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 652f37c..a04e433 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -181,6 +181,7 @@
 
 void innovator_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 #ifdef CONFIG_ARCH_OMAP15XX
@@ -285,7 +286,7 @@
 
 static void __init innovator_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index 58f7839..60d5f8a 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -65,6 +65,7 @@
 
 static void __init netstar_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 }
@@ -108,7 +109,7 @@
 
 static void __init netstar_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 }
 
 #define MACHINE_PANICED		1
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index e5d126e..543fa13 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -169,6 +169,7 @@
 
 static void __init osk_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 	osk_init_smc91x();
@@ -269,7 +270,7 @@
 
 static void __init osk_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_OSK, "TI-OSK")
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 67fada2..e488f72 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -34,6 +34,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 }
 
@@ -72,7 +73,7 @@
 
 static void __init omap_generic_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 88708a0..3913a3c 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -144,6 +144,7 @@
 
 void omap_perseus2_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 	perseus2_init_smc91x();
@@ -160,7 +161,7 @@
 
 static void __init omap_perseus2_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 	iotable_init(omap_perseus2_io_desc,
 		     ARRAY_SIZE(omap_perseus2_io_desc));
 
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 959b4b8..bfd5fdd 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -162,6 +162,7 @@
 
 static void __init voiceblue_init_irq(void)
 {
+	omap1_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 }
@@ -206,7 +207,7 @@
 
 static void __init voiceblue_map_io(void)
 {
-	omap_map_common_io();
+	omap1_map_common_io();
 }
 
 #define MACHINE_PANICED		1
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index a7a19f7..82d556b 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
+#include <asm/tlb.h>
 #include <asm/mach/map.h>
 #include <asm/io.h>
 #include <asm/arch/mux.h>
@@ -83,15 +84,24 @@
 };
 #endif
 
-static int initialized = 0;
-
-static void __init _omap_map_io(void)
+/*
+ * Maps common IO regions for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_map_common_io(void)
 {
-	initialized = 1;
-
-	/* We have to initialize the IO space mapping before we can run
-	 * cpu_is_omapxxx() macros. */
 	iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+
+	/* Normally devicemaps_init() would flush caches and tlb after
+	 * mdesc->map_io(), but we must also do it here because of the CPU
+	 * revision check below.
+	 */
+	local_flush_tlb_all();
+	flush_cache_all();
+
+	/* We want to check CPU revision early for cpu_is_omapxxxx() macros.
+	 * IO space mapping must be initialized before we can do that.
+	 */
 	omap_check_revision();
 
 #ifdef CONFIG_ARCH_OMAP730
@@ -111,7 +121,14 @@
 #endif
 
 	omap_sram_init();
+}
 
+/*
+ * Common low-level hardware init for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_init_common_hw()
+{
 	/* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
 	 * on a Posted Write in the TIPB Bridge".
 	 */
@@ -121,16 +138,7 @@
 	/* Must init clocks early to assure that timer interrupt works
 	 */
 	omap1_clk_init();
-}
 
-/*
- * This should only get called from board specific init
- */
-void __init omap_map_common_io(void)
-{
-	if (!initialized) {
-		_omap_map_io();
-		omap1_mux_init();
-	}
+	omap1_mux_init();
 }
 
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index b937123..eaecbf4 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -33,6 +33,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+	omap2_init_common_hw();
 	omap_init_irq();
 }
 
@@ -64,7 +65,7 @@
 
 static void __init omap_generic_map_io(void)
 {
-	omap_map_common_io();
+	omap2_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index c3c35d4..a300d63 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -136,6 +136,7 @@
 
 static void __init omap_h4_init_irq(void)
 {
+	omap2_init_common_hw();
 	omap_init_irq();
 	omap_gpio_init();
 	h4_init_smc91x();
@@ -181,7 +182,7 @@
 
 static void __init omap_h4_map_io(void)
 {
-	omap_map_common_io();
+	omap2_map_common_io();
 }
 
 MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 4a222f5..4303d98 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -182,7 +182,7 @@
 static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
 {
 	void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
-	void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET;
+	void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
 	u32 val;
 
 	val = readl(sys_osc) & ~0x7ffff;
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index af2f3d5..08489ef 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -40,7 +40,6 @@
 #include <linux/mutex.h>
 
 #include <asm/hardware.h>
-#include <asm/atomic.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
@@ -59,22 +58,18 @@
 void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
 {
 	unsigned long clkcon;
-	unsigned long flags;
-
-	local_irq_save(flags);
 
 	clkcon = __raw_readl(S3C2410_CLKCON);
-	clkcon &= ~clocks;
 
 	if (enable)
 		clkcon |= clocks;
+	else
+		clkcon &= ~clocks;
 
 	/* ensure none of the special function bits set */
 	clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
 
 	__raw_writel(clkcon, S3C2410_CLKCON);
-
-	local_irq_restore(flags);
 }
 
 /* enable and disable calls for use with the clk struct */
@@ -138,16 +133,32 @@
 
 int clk_enable(struct clk *clk)
 {
-	if (IS_ERR(clk))
+	if (IS_ERR(clk) || clk == NULL)
 		return -EINVAL;
 
-	return (clk->enable)(clk, 1);
+	clk_enable(clk->parent);
+
+	mutex_lock(&clocks_mutex);
+
+	if ((clk->usage++) == 0)
+		(clk->enable)(clk, 1);
+
+	mutex_unlock(&clocks_mutex);
+	return 0;
 }
 
 void clk_disable(struct clk *clk)
 {
-	if (!IS_ERR(clk))
+	if (IS_ERR(clk) || clk == NULL)
+		return;
+
+	mutex_lock(&clocks_mutex);
+
+	if ((--clk->usage) == 0)
 		(clk->enable)(clk, 0);
+
+	mutex_unlock(&clocks_mutex);
+	clk_disable(clk->parent);
 }
 
 
@@ -361,6 +372,14 @@
 	if (clk->enable == NULL)
 		clk->enable = clk_null_enable;
 
+	/* if this is a standard clock, set the usage state */
+
+	if (clk->ctrlbit) {
+		unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
+
+		clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0;
+	}
+
 	/* add to the list of available clocks */
 
 	mutex_lock(&clocks_mutex);
@@ -402,6 +421,8 @@
 	 * the LCD clock if it is not needed.
 	*/
 
+	mutex_lock(&clocks_mutex);
+
 	s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
 	s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
 	s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
@@ -409,6 +430,8 @@
 	s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
 	s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
 
+	mutex_unlock(&clocks_mutex);
+
 	/* assume uart clocks are correctly setup */
 
 	/* register our clocks */
diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h
index 177d5c8..eb5c95d 100644
--- a/arch/arm/mach-s3c2410/clock.h
+++ b/arch/arm/mach-s3c2410/clock.h
@@ -16,6 +16,7 @@
 	struct clk           *parent;
 	const char           *name;
 	int		      id;
+	int		      usage;
 	unsigned long         rate;
 	unsigned long         ctrlbit;
 	int		    (*enable)(struct clk *, int enable);
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index b8d994a..0a47d38 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -275,6 +275,11 @@
 	},
 	[1] = {
 		.start = IRQ_TC,
+		.end   = IRQ_TC,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_ADC,
 		.end   = IRQ_ADC,
 		.flags = IORESOURCE_IRQ,
 	}
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 792f663..ee82763 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 
 #include <asm/mach/map.h>
+#include <asm/tlb.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
@@ -96,6 +97,14 @@
 	       omap_sram_io_desc[0].length);
 
 	/*
+	 * Normally devicemaps_init() would flush caches and tlb after
+	 * mdesc->map_io(), but since we're called from map_io(), we
+	 * must do it here.
+	 */
+	local_flush_tlb_all();
+	flush_cache_all();
+
+	/*
 	 * Looks like we need to preserve some bootloader code at the
 	 * beginning of SRAM for jumping to flash for reboot to work...
 	 */
diff --git a/arch/cris/Makefile b/arch/cris/Makefile
index ea65d58..ee11469 100644
--- a/arch/cris/Makefile
+++ b/arch/cris/Makefile
@@ -119,7 +119,7 @@
 	@ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib
 	@ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch
 	@ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
-	@ln -sfn $(SRC_ARCH)/$(SARCH)/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
+	@ln -sfn $(SRC_ARCH)/$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c
 	@touch $@
 
 # Create link to sub arch includes
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index f214f74..961c0d5 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -202,18 +202,18 @@
 		  	int i;
 			unsigned long tmp;
 			
+			ret = 0;
 			for (i = 0; i <= PT_MAX; i++) {
 				tmp = get_reg(child, i);
 				
 				if (put_user(tmp, datap)) {
 					ret = -EFAULT;
-					goto out_tsk;
+					break;
 				}
 				
 				data += sizeof(long);
 			}
 
-			ret = 0;
 			break;
 		}
 
@@ -222,10 +222,11 @@
 			int i;
 			unsigned long tmp;
 			
+			ret = 0;
 			for (i = 0; i <= PT_MAX; i++) {
 				if (get_user(tmp, datap)) {
 					ret = -EFAULT;
-					goto out_tsk;
+					break;
 				}
 				
 				if (i == PT_DCCR) {
@@ -237,7 +238,6 @@
 				data += sizeof(long);
 			}
 			
-			ret = 0;
 			break;
 		}
 
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index d11206e..1ba57ef 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -24,7 +24,6 @@
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
 struct screen_info screen_info;
 
 extern int root_mountflags;
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index d86c865..0afec85 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -442,6 +442,7 @@
 
 config HIGHMEM64G
 	bool "64GB"
+	depends on X86_CMPXCHG64
 	help
 	  Select this if you have a 32-bit processor and more than 4
 	  gigabytes of physical RAM.
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index f21fa0d..79577f0 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -248,10 +248,17 @@
 
 	acpi_table_print_madt_entry(header);
 
-	/* Register even disabled CPUs for cpu hotplug */
+	/* Record local apic id only when enabled */
+	if (processor->flags.enabled)
+		x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
 
-	x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
-
+	/*
+	 * We need to register disabled CPU as well to permit
+	 * counting disabled CPUs. This allows us to size
+	 * cpus_possible_map more accurately, to permit
+	 * to not preallocating memory for all NR_CPUS
+	 * when we use CPU hotplug.
+	 */
 	mp_register_lapic(processor->id,	/* APIC ID */
 			  processor->flags.enabled);	/* Enabled? */
 
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index acd3f1e..f39e09e 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -75,8 +75,10 @@
 	 * holds up an irq slot - in excessive cases (when multiple
 	 * unexpected vectors occur) that might lock up the APIC
 	 * completely.
+	 * But only ack when the APIC is enabled -AK
 	 */
-	ack_APIC_irq();
+	if (cpu_has_apic)
+		ack_APIC_irq();
 }
 
 void __init apic_intr_init(void)
@@ -1303,6 +1305,7 @@
 	if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
 		printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
 			boot_cpu_physical_apicid);
+		clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
 		return -1;
 	}
 
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 333578a..0810f81f 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -282,3 +282,11 @@
 }
 
 //early_arch_initcall(amd_init_cpu);
+
+static int __init amd_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_AMD] = NULL;
+	return 0;
+}
+
+late_initcall(amd_exit_cpu);
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c
index 0dd92a2..f52669e 100644
--- a/arch/i386/kernel/cpu/centaur.c
+++ b/arch/i386/kernel/cpu/centaur.c
@@ -470,3 +470,11 @@
 }
 
 //early_arch_initcall(centaur_init_cpu);
+
+static int __init centaur_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_CENTAUR] = NULL;
+	return 0;
+}
+
+late_initcall(centaur_exit_cpu);
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 15aee26..7eb9213 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -44,6 +44,7 @@
 
 static struct cpu_dev default_cpu = {
 	.c_init	= default_init,
+	.c_vendor = "Unknown",
 };
 static struct cpu_dev * this_cpu = &default_cpu;
 
@@ -150,6 +151,7 @@
 {
 	char *v = c->x86_vendor_id;
 	int i;
+	static int printed;
 
 	for (i = 0; i < X86_VENDOR_NUM; i++) {
 		if (cpu_devs[i]) {
@@ -159,10 +161,17 @@
 				c->x86_vendor = i;
 				if (!early)
 					this_cpu = cpu_devs[i];
-				break;
+				return;
 			}
 		}
 	}
+	if (!printed) {
+		printed++;
+		printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n");
+		printk(KERN_ERR "CPU: Your system may be unstable.\n");
+	}
+	c->x86_vendor = X86_VENDOR_UNKNOWN;
+	this_cpu = &default_cpu;
 }
 
 
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index 7501597..00f2e05 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -345,7 +345,7 @@
 /*
  * Handle National Semiconductor branded processors
  */
-static void __devinit init_nsc(struct cpuinfo_x86 *c)
+static void __init init_nsc(struct cpuinfo_x86 *c)
 {
 	/* There may be GX1 processors in the wild that are branded
 	 * NSC and not Cyrix.
@@ -444,6 +444,14 @@
 
 //early_arch_initcall(cyrix_init_cpu);
 
+static int __init cyrix_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_CYRIX] = NULL;
+	return 0;
+}
+
+late_initcall(cyrix_exit_cpu);
+
 static struct cpu_dev nsc_cpu_dev __initdata = {
 	.c_vendor	= "NSC",
 	.c_ident 	= { "Geode by NSC" },
@@ -458,3 +466,11 @@
 }
 
 //early_arch_initcall(nsc_init_cpu);
+
+static int __init nsc_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_NSC] = NULL;
+	return 0;
+}
+
+late_initcall(nsc_exit_cpu);
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index af591c7..ffe58ce 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -152,6 +152,7 @@
 	return 0;
 }
 
+/* will only be called once; __init is safe here */
 static int __init find_num_cache_leaves(void)
 {
 	unsigned int		eax, ebx, ecx, edx;
diff --git a/arch/i386/kernel/cpu/nexgen.c b/arch/i386/kernel/cpu/nexgen.c
index 30898a2..ad87fa5 100644
--- a/arch/i386/kernel/cpu/nexgen.c
+++ b/arch/i386/kernel/cpu/nexgen.c
@@ -61,3 +61,11 @@
 }
 
 //early_arch_initcall(nexgen_init_cpu);
+
+static int __init nexgen_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_NEXGEN] = NULL;
+	return 0;
+}
+
+late_initcall(nexgen_exit_cpu);
diff --git a/arch/i386/kernel/cpu/rise.c b/arch/i386/kernel/cpu/rise.c
index 8602425..d08d5a2 100644
--- a/arch/i386/kernel/cpu/rise.c
+++ b/arch/i386/kernel/cpu/rise.c
@@ -51,3 +51,11 @@
 }
 
 //early_arch_initcall(rise_init_cpu);
+
+static int __init rise_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_RISE] = NULL;
+	return 0;
+}
+
+late_initcall(rise_exit_cpu);
diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c
index fc42638..bdbeb77 100644
--- a/arch/i386/kernel/cpu/transmeta.c
+++ b/arch/i386/kernel/cpu/transmeta.c
@@ -84,7 +84,7 @@
 #endif
 }
 
-static void transmeta_identify(struct cpuinfo_x86 * c)
+static void __init transmeta_identify(struct cpuinfo_x86 * c)
 {
 	u32 xlvl;
 	generic_identify(c);
@@ -111,3 +111,11 @@
 }
 
 //early_arch_initcall(transmeta_init_cpu);
+
+static int __init transmeta_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_TRANSMETA] = NULL;
+	return 0;
+}
+
+late_initcall(transmeta_exit_cpu);
diff --git a/arch/i386/kernel/cpu/umc.c b/arch/i386/kernel/cpu/umc.c
index 264fcad..2cd988f 100644
--- a/arch/i386/kernel/cpu/umc.c
+++ b/arch/i386/kernel/cpu/umc.c
@@ -31,3 +31,11 @@
 }
 
 //early_arch_initcall(umc_init_cpu);
+
+static int __init umc_exit_cpu(void)
+{
+	cpu_devs[X86_VENDOR_UMC] = NULL;
+	return 0;
+}
+
+late_initcall(umc_exit_cpu);
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index d661703..63f39a7 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -138,7 +138,7 @@
 	if (nmi_watchdog == NMI_LOCAL_APIC)
 		smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
 
-	for (cpu = 0; cpu < NR_CPUS; cpu++)
+	for_each_cpu(cpu)
 		prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
 	local_irq_enable();
 	mdelay((10*1000)/nmi_hz); // wait 10 ticks
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 2185377..0480454 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -297,8 +297,10 @@
 
 	if (user_mode(regs))
 		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
-	printk(" EFLAGS: %08lx    %s  (%s)\n",
-	       regs->eflags, print_tainted(), system_utsname.release);
+	printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
+	       regs->eflags, print_tainted(), system_utsname.release,
+	       (int)strcspn(system_utsname.version, " "),
+	       system_utsname.version);
 	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
 		regs->eax,regs->ebx,regs->ecx,regs->edx);
 	printk("ESI: %08lx EDI: %08lx EBP: %08lx",
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 1b66592..5a8b3fb 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -309,3 +309,4 @@
 	.long sys_faccessat
 	.long sys_pselect6
 	.long sys_ppoll
+	.long sys_unshare		/* 310 */
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 0aaebf3..b814dbd 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -166,7 +166,8 @@
 		stack = (unsigned long*)context->previous_esp;
 		if (!stack)
 			break;
-		printk(KERN_EMERG " =======================\n");
+		printk(log_lvl);
+		printk(" =======================\n");
 	}
 }
 
@@ -239,9 +240,11 @@
 	}
 	print_modules();
 	printk(KERN_EMERG "CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\n"
-			"EFLAGS: %08lx   (%s) \n",
+			"EFLAGS: %08lx   (%s %.*s) \n",
 		smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-		print_tainted(), regs->eflags, system_utsname.release);
+		print_tainted(), regs->eflags, system_utsname.release,
+		(int)strcspn(system_utsname.version, " "),
+		system_utsname.version);
 	print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
 	printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
 		regs->eax, regs->ebx, regs->ecx, regs->edx);
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 199eeaf..845cd09 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -194,7 +194,6 @@
 	default "7" if MCKINLEY
 	default "6" if ITANIUM
 
-# align cache-sensitive data to 64 bytes
 config IA64_CYCLONE
 	bool "Cyclone (EXA) Time Source support"
 	help
@@ -374,6 +373,9 @@
 	  To use this option, you have to ensure that the "/proc file system
 	  support" (CONFIG_PROC_FS) is enabled, too.
 
+config SGI_SN
+	def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
+
 source "drivers/firmware/Kconfig"
 
 source "fs/Kconfig.binfmt"
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
index d58003f..c9104bf 100644
--- a/arch/ia64/dig/setup.c
+++ b/arch/ia64/dig/setup.c
@@ -25,16 +25,6 @@
 #include <asm/machvec.h>
 #include <asm/system.h>
 
-/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present.  In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator.  Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-char drive_info[4*16];
-
 void __init
 dig_setup (char **cmdline_p)
 {
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
index acc0f13..056f7a6 100644
--- a/arch/ia64/kernel/sal.c
+++ b/arch/ia64/kernel/sal.c
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
+#include <asm/delay.h>
 #include <asm/page.h>
 #include <asm/sal.h>
 #include <asm/pal.h>
@@ -214,6 +215,78 @@
 static void __init sal_desc_ap_wakeup(void *p) { }
 #endif
 
+/*
+ * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading
+ * cr.ivr, but it never writes cr.eoi.  This leaves any interrupt marked as
+ * "in-service" and masks other interrupts of equal or lower priority.
+ *
+ * HP internal defect reports: F1859, F2775, F3031.
+ */
+static int sal_cache_flush_drops_interrupts;
+
+static void __init
+check_sal_cache_flush (void)
+{
+	unsigned long flags, itv;
+	int cpu;
+	u64 vector;
+
+	cpu = get_cpu();
+	local_irq_save(flags);
+
+	/*
+	 * Schedule a timer interrupt, wait until it's reported, and see if
+	 * SAL_CACHE_FLUSH drops it.
+	 */
+	itv = ia64_get_itv();
+	BUG_ON((itv & (1 << 16)) == 0);
+
+	ia64_set_itv(IA64_TIMER_VECTOR);
+	ia64_set_itm(ia64_get_itc() + 1000);
+
+	while (!ia64_get_irr(IA64_TIMER_VECTOR))
+		cpu_relax();
+
+	ia64_sal_cache_flush(3);
+
+	if (ia64_get_irr(IA64_TIMER_VECTOR)) {
+		vector = ia64_get_ivr();
+		ia64_eoi();
+		WARN_ON(vector != IA64_TIMER_VECTOR);
+	} else {
+		sal_cache_flush_drops_interrupts = 1;
+		printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; "
+			"PAL_CACHE_FLUSH will be used instead\n");
+		ia64_eoi();
+	}
+
+	ia64_set_itv(itv);
+	local_irq_restore(flags);
+	put_cpu();
+}
+
+s64
+ia64_sal_cache_flush (u64 cache_type)
+{
+	struct ia64_sal_retval isrv;
+
+	if (sal_cache_flush_drops_interrupts) {
+		unsigned long flags;
+		u64 progress;
+		s64 rc;
+
+		progress = 0;
+		local_irq_save(flags);
+		rc = ia64_pal_cache_flush(cache_type,
+			PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL);
+		local_irq_restore(flags);
+		return rc;
+	}
+
+	SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
+	return isrv.status;
+}
+
 void __init
 ia64_sal_init (struct ia64_sal_systab *systab)
 {
@@ -262,6 +335,8 @@
 		}
 		p += SAL_DESC_SIZE(*p);
 	}
+
+	check_sal_cache_flush();
 }
 
 int
diff --git a/arch/ia64/sn/Makefile b/arch/ia64/sn/Makefile
index a269f6d..79a7df0 100644
--- a/arch/ia64/sn/Makefile
+++ b/arch/ia64/sn/Makefile
@@ -9,6 +9,4 @@
 # Makefile for the sn ia64 subplatform
 #
 
-CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
-
 obj-y += kernel/ pci/
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
index 4351c4f..3e9b4ee 100644
--- a/arch/ia64/sn/kernel/Makefile
+++ b/arch/ia64/sn/kernel/Makefile
@@ -7,6 +7,8 @@
 # Copyright (C) 1999,2001-2005 Silicon Graphics, Inc.  All Rights Reserved.
 #
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y				+= setup.o bte.o bte_error.o irq.o mca.o idle.o \
 				   huberror.o io_init.o iomv.o klconflib.o sn2/
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index dd73c0c..1f11db4 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/config.h>
@@ -186,18 +186,13 @@
 
 	/* Initialize the notification to a known value. */
 	*bte->most_rcnt_na = BTE_WORD_BUSY;
-	notif_phys_addr = TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na));
+	notif_phys_addr = (u64)bte->most_rcnt_na;
 
-	if (is_shub2()) {
-		src = SH2_TIO_PHYS_TO_DMA(src);
-		dest = SH2_TIO_PHYS_TO_DMA(dest);
-		notif_phys_addr = SH2_TIO_PHYS_TO_DMA(notif_phys_addr);
-	}
 	/* Set the source and destination registers */
-	BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src))));
-	BTE_SRC_STORE(bte, TO_PHYS(src));
-	BTE_PRINTKV(("IBDA = 0x%lx)\n", (TO_PHYS(dest))));
-	BTE_DEST_STORE(bte, TO_PHYS(dest));
+	BTE_PRINTKV(("IBSA = 0x%lx)\n", src));
+	BTE_SRC_STORE(bte, src);
+	BTE_PRINTKV(("IBDA = 0x%lx)\n", dest));
+	BTE_DEST_STORE(bte, dest);
 
 	/* Set the notification register */
 	BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr));
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index a4c7815..d7e4d79 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -208,7 +208,7 @@
  * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
  *	each node in the system.
  */
-static void sn_fixup_ionodes(void)
+static void __init sn_fixup_ionodes(void)
 {
 	struct sn_flush_device_kernel *sn_flush_device_kernel;
 	struct sn_flush_device_kernel *dev_entry;
@@ -467,6 +467,13 @@
 		pcidev_info->pdi_sn_irq_info = NULL;
 		kfree(sn_irq_info);
 	}
+
+	/*
+	 * MSI currently not supported on altix.  Remove this when
+	 * the MSI abstraction patches are integrated into the kernel
+	 * (sometime after 2.6.16 releases)
+	 */
+	dev->no_msi = 1;
 }
 
 /*
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index ec37084..74d87d9 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -5,11 +5,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/irq.h>
 #include <linux/spinlock.h>
+#include <linux/init.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/intr.h>
@@ -76,17 +77,15 @@
 
 static void sn_ack_irq(unsigned int irq)
 {
-	u64 event_occurred, mask = 0;
+	u64 event_occurred, mask;
 
 	irq = irq & 0xff;
-	event_occurred =
-	    HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
+	event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
 	mask = event_occurred & SH_ALL_INT_MASK;
-	HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS),
-	      mask);
+	HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
 	__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
 
-	move_irq(irq);
+	move_native_irq(irq);
 }
 
 static void sn_end_irq(unsigned int irq)
@@ -219,9 +218,8 @@
 		pdacpu(cpu)->sn_last_irq = irq;
 	}
 
-	if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) {
+	if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq)
 		pdacpu(cpu)->sn_first_irq = irq;
-	}
 }
 
 static void unregister_intr_pda(struct sn_irq_info *sn_irq_info)
@@ -289,7 +287,7 @@
 	list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
 	spin_unlock(&sn_irq_info_lock);
 
-	(void)register_intr_pda(sn_irq_info);
+	register_intr_pda(sn_irq_info);
 }
 
 void sn_irq_unfixup(struct pci_dev *pci_dev)
@@ -419,7 +417,7 @@
 	rcu_read_unlock();
 }
 
-void sn_irq_lh_init(void)
+void __init sn_irq_lh_init(void)
 {
 	int i;
 
@@ -434,5 +432,4 @@
 
 		INIT_LIST_HEAD(sn_irq_lh[i]);
 	}
-
 }
diff --git a/arch/ia64/sn/kernel/klconflib.c b/arch/ia64/sn/kernel/klconflib.c
index 0f11a32..87682b4 100644
--- a/arch/ia64/sn/kernel/klconflib.c
+++ b/arch/ia64/sn/kernel/klconflib.c
@@ -78,31 +78,30 @@
 	position = MODULE_GET_BPOS(m);
 
 	if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) {
-	    /* Brief module number format, eg. 002c15 */
+		/* Brief module number format, eg. 002c15 */
 
-	    /* Decompress the rack number */
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
+		/* Decompress the rack number */
+		*buffer++ = '0' + RACK_GET_CLASS(rack);
+		*buffer++ = '0' + RACK_GET_GROUP(rack);
+		*buffer++ = '0' + RACK_GET_NUM(rack);
 
-	    /* Add the brick type */
-	    *buffer++ = brickchar;
+		/* Add the brick type */
+		*buffer++ = brickchar;
 	}
 	else if (fmt == MODULE_FORMAT_LONG) {
-	    /* Fuller hwgraph format, eg. rack/002/bay/15 */
+		/* Fuller hwgraph format, eg. rack/002/bay/15 */
 
-	    strcpy(buffer, "rack" "/");  buffer += strlen(buffer);
+		strcpy(buffer, "rack" "/");  buffer += strlen(buffer);
 
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
+		*buffer++ = '0' + RACK_GET_CLASS(rack);
+		*buffer++ = '0' + RACK_GET_GROUP(rack);
+		*buffer++ = '0' + RACK_GET_NUM(rack);
 
-	    strcpy(buffer, "/" "bay" "/");  buffer += strlen(buffer);
+		strcpy(buffer, "/" "bay" "/");  buffer += strlen(buffer);
 	}
 
 	/* Add the bay position, using at least two digits */
 	if (position < 10)
-	    *buffer++ = '0';
+		*buffer++ = '0';
 	sprintf(buffer, "%d", position);
-
 }
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e510dce..aac1ba3 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -125,20 +125,6 @@
 };
 
 /*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present.  In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator.  Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-#ifdef CONFIG_IA64_GENERIC
-extern char drive_info[4 * 16];
-#else
-char drive_info[4 * 16];
-#endif
-
-/*
  * This routine can only be used during init, since
  * smp_boot_data is an init data structure.
  * We have to use smp_boot_data.cpu_phys_id to find
@@ -209,7 +195,7 @@
 }
 
 extern int platform_intr_list[];
-static int __initdata shub_1_1_found = 0;
+static int __initdata shub_1_1_found;
 
 /*
  * sn_check_for_wars
@@ -578,13 +564,17 @@
 			sn_prom_type = 2;
 		else
 			sn_prom_type = 1;
-		printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake");
+		printk(KERN_INFO "Running on medusa with %s PROM\n",
+		       (sn_prom_type == 1) ? "real" : "fake");
 	}
 
 	memset(pda, 0, sizeof(pda));
-	if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
-				&sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
-				&sn_coherency_id, &sn_region_size))
+	if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2,
+				&sn_hub_info->nasid_bitmask,
+				&sn_hub_info->nasid_shift,
+				&sn_system_size, &sn_sharing_domain_size,
+				&sn_partition_id, &sn_coherency_id,
+				&sn_region_size))
 		BUG();
 	sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;
 
@@ -716,7 +706,8 @@
 	for_each_online_node(node) {
 		kl_config_hdr_t *klgraph_header;
 		nasid = cnodeid_to_nasid(node);
-		if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL)
+		klgraph_header = ia64_sn_get_klconfig_addr(nasid);
+		if (klgraph_header == NULL)
 			BUG();
 		brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
 		while (brd) {
@@ -734,7 +725,7 @@
 {
 	long cpu;
 
-	for (cpu=0; cpu < NR_CPUS; cpu++)
+	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		if (cpuid_to_nasid(cpu) == nasid &&
 					cpuid_to_slice(cpu) == slice)
 			return cpu;
diff --git a/arch/ia64/sn/kernel/sn2/Makefile b/arch/ia64/sn/kernel/sn2/Makefile
index 170bde4..99e1776 100644
--- a/arch/ia64/sn/kernel/sn2/Makefile
+++ b/arch/ia64/sn/kernel/sn2/Makefile
@@ -9,5 +9,7 @@
 # sn2 specific kernel files
 #
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
 	 prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 471bbaa..f153a4c 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/init.h>
@@ -46,104 +46,28 @@
 
 static  __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
 
-void sn2_ptc_deadlock_recovery(short *, short, int, volatile unsigned long *, unsigned long data0,
-	volatile unsigned long *, unsigned long data1);
+void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long,
+	volatile unsigned long *, unsigned long);
 
-#ifdef DEBUG_PTC
 /*
- * ptctest:
- *
- * 	xyz - 3 digit hex number:
- * 		x - Force PTC purges to use shub:
- * 			0 - no force
- * 			1 - force
- * 		y - interupt enable
- * 			0 - disable interrupts
- * 			1 - leave interuupts enabled
- * 		z - type of lock:
- * 			0 - global lock
- * 			1 - node local lock
- * 			2 - no lock
- *
- *   	Note: on shub1, only ptctest == 0 is supported. Don't try other values!
+ * Note: some is the following is captured here to make degugging easier
+ * (the macros make more sense if you see the debug patch - not posted)
  */
-
-static unsigned int sn2_ptctest = 0;
-
-static int __init ptc_test(char *str)
-{
-	get_option(&str, &sn2_ptctest);
-	return 1;
-}
-__setup("ptctest=", ptc_test);
-
-static inline int ptc_lock(unsigned long *flagp)
-{
-	unsigned long opt = sn2_ptctest & 255;
-
-	switch (opt) {
-	case 0x00:
-		spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
-		break;
-	case 0x01:
-		spin_lock_irqsave(&sn_nodepda->ptc_lock, *flagp);
-		break;
-	case 0x02:
-		local_irq_save(*flagp);
-		break;
-	case 0x10:
-		spin_lock(&sn2_global_ptc_lock);
-		break;
-	case 0x11:
-		spin_lock(&sn_nodepda->ptc_lock);
-		break;
-	case 0x12:
-		break;
-	default:
-		BUG();
-	}
-	return opt;
-}
-
-static inline void ptc_unlock(unsigned long flags, int opt)
-{
-	switch (opt) {
-	case 0x00:
-		spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
-		break;
-	case 0x01:
-		spin_unlock_irqrestore(&sn_nodepda->ptc_lock, flags);
-		break;
-	case 0x02:
-		local_irq_restore(flags);
-		break;
-	case 0x10:
-		spin_unlock(&sn2_global_ptc_lock);
-		break;
-	case 0x11:
-		spin_unlock(&sn_nodepda->ptc_lock);
-		break;
-	case 0x12:
-		break;
-	default:
-		BUG();
-	}
-}
-#else
-
 #define sn2_ptctest	0
+#define local_node_uses_ptc_ga(sh1)	((sh1) ? 1 : 0)
+#define max_active_pio(sh1)		((sh1) ? 32 : 7)
+#define reset_max_active_on_deadlock()	1
+#define PTC_LOCK(sh1)			((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock)
 
-static inline int ptc_lock(unsigned long *flagp)
+static inline void ptc_lock(int sh1, unsigned long *flagp)
 {
-	spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
-	return 0;
+	spin_lock_irqsave(PTC_LOCK(sh1), *flagp);
 }
 
-static inline void ptc_unlock(unsigned long flags, int opt)
+static inline void ptc_unlock(int sh1, unsigned long flags)
 {
-	spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
+	spin_unlock_irqrestore(PTC_LOCK(sh1), flags);
 }
-#endif
 
 struct ptc_stats {
 	unsigned long ptc_l;
@@ -151,27 +75,30 @@
 	unsigned long shub_ptc_flushes;
 	unsigned long nodes_flushed;
 	unsigned long deadlocks;
+	unsigned long deadlocks2;
 	unsigned long lock_itc_clocks;
 	unsigned long shub_itc_clocks;
 	unsigned long shub_itc_clocks_max;
+	unsigned long shub_ptc_flushes_not_my_mm;
 };
 
 static inline unsigned long wait_piowc(void)
 {
-	volatile unsigned long *piows, zeroval;
-	unsigned long ws;
+	volatile unsigned long *piows;
+	unsigned long zeroval, ws;
 
 	piows = pda->pio_write_status_addr;
 	zeroval = pda->pio_write_status_val;
 	do {
 		cpu_relax();
 	} while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval);
-	return ws;
+	return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0;
 }
 
 void sn_tlb_migrate_finish(struct mm_struct *mm)
 {
-	if (mm == current->mm)
+	/* flush_tlb_mm is inefficient if more than 1 users of mm */
+	if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1)
 		flush_tlb_mm(mm);
 }
 
@@ -201,12 +128,14 @@
 sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
 		     unsigned long end, unsigned long nbits)
 {
-	int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
-	int mymm = (mm == current->active_mm && current->mm);
+	int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid;
+	int mymm = (mm == current->active_mm && mm == current->mm);
+	int use_cpu_ptcga;
 	volatile unsigned long *ptc0, *ptc1;
-	unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
+	unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0;
 	short nasids[MAX_NUMNODES], nix;
 	nodemask_t nodes_flushed;
+	int active, max_active, deadlock;
 
 	nodes_clear(nodes_flushed);
 	i = 0;
@@ -267,41 +196,56 @@
 	
 
 	mynasid = get_nasid();
+	use_cpu_ptcga = local_node_uses_ptc_ga(shub1);
+	max_active = max_active_pio(shub1);
 
 	itc = ia64_get_itc();
-	opt = ptc_lock(&flags);
+	ptc_lock(shub1, &flags);
 	itc2 = ia64_get_itc();
+
 	__get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc;
 	__get_cpu_var(ptcstats).shub_ptc_flushes++;
 	__get_cpu_var(ptcstats).nodes_flushed += nix;
+	if (!mymm)
+		 __get_cpu_var(ptcstats).shub_ptc_flushes_not_my_mm++;
 
+	if (use_cpu_ptcga && !mymm) {
+		old_rr = ia64_get_rr(start);
+		ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8));
+		ia64_srlz_d();
+	}
+
+	wait_piowc();
 	do {
 		if (shub1)
 			data1 = start | (1UL << SH1_PTC_1_START_SHFT);
 		else
 			data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
-		for (i = 0; i < nix; i++) {
+		deadlock = 0;
+		active = 0;
+		for (ibegin = 0, i = 0; i < nix; i++) {
 			nasid = nasids[i];
-			if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) {
+			if (use_cpu_ptcga && unlikely(nasid == mynasid)) {
 				ia64_ptcga(start, nbits << 2);
 				ia64_srlz_i();
 			} else {
 				ptc0 = CHANGE_NASID(nasid, ptc0);
 				if (ptc1)
 					ptc1 = CHANGE_NASID(nasid, ptc1);
-				pio_atomic_phys_write_mmrs(ptc0, data0, ptc1,
-							   data1);
-				flushed = 1;
+				pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
+				active++;
+			}
+			if (active >= max_active || i == (nix - 1)) {
+				if ((deadlock = wait_piowc())) {
+					sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1);
+					if (reset_max_active_on_deadlock())
+						max_active = 1;
+				}
+				active = 0;
+				ibegin = i + 1;
 			}
 		}
-		if (flushed
-		    && (wait_piowc() &
-				(SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK))) {
-			sn2_ptc_deadlock_recovery(nasids, nix, mynasid, ptc0, data0, ptc1, data1);
-		}
-
 		start += (1UL << nbits);
-
 	} while (start < end);
 
 	itc2 = ia64_get_itc() - itc2;
@@ -309,7 +253,12 @@
 	if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max)
 		__get_cpu_var(ptcstats).shub_itc_clocks_max = itc2;
 
-	ptc_unlock(flags, opt);
+	if (old_rr) {
+		ia64_set_rr(start, old_rr);
+		ia64_srlz_d();
+	}
+
+	ptc_unlock(shub1, flags);
 
 	preempt_enable();
 }
@@ -321,27 +270,30 @@
  * TLB flush transaction.  The recovery sequence is somewhat tricky & is
  * coded in assembly language.
  */
-void sn2_ptc_deadlock_recovery(short *nasids, short nix, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
+void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
 	volatile unsigned long *ptc1, unsigned long data1)
 {
-	extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
+	extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
 	        volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long);
 	short nasid, i;
-	unsigned long *piows, zeroval;
+	unsigned long *piows, zeroval, n;
 
 	__get_cpu_var(ptcstats).deadlocks++;
 
 	piows = (unsigned long *) pda->pio_write_status_addr;
 	zeroval = pda->pio_write_status_val;
 
-	for (i=0; i < nix; i++) {
+
+	for (i=ib; i <= ie; i++) {
 		nasid = nasids[i];
-		if (!(sn2_ptctest & 3) && nasid == mynasid)
+		if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid)
 			continue;
 		ptc0 = CHANGE_NASID(nasid, ptc0);
 		if (ptc1)
 			ptc1 = CHANGE_NASID(nasid, ptc1);
-		sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
+
+		n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
+		__get_cpu_var(ptcstats).deadlocks2 += n;
 	}
 
 }
@@ -452,20 +404,22 @@
 	cpu = *(loff_t *) data;
 
 	if (!cpu) {
-		seq_printf(file, "# ptc_l change_rid shub_ptc_flushes shub_nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max\n");
+		seq_printf(file,
+			   "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2\n");
 		seq_printf(file, "# ptctest %d\n", sn2_ptctest);
 	}
 
 	if (cpu < NR_CPUS && cpu_online(cpu)) {
 		stat = &per_cpu(ptcstats, cpu);
-		seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
+		seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
 				stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
 				stat->deadlocks,
 				1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
 				1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
-				1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec);
+				1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec,
+				stat->shub_ptc_flushes_not_my_mm,
+				stat->deadlocks2);
 	}
-
 	return 0;
 }
 
@@ -476,7 +430,7 @@
 	.show = sn2_ptc_seq_show
 };
 
-int sn2_ptc_proc_open(struct inode *inode, struct file *file)
+static int sn2_ptc_proc_open(struct inode *inode, struct file *file)
 {
 	return seq_open(file, &sn2_ptc_seq_ops);
 }
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index c75f8ae..9cd460d 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -575,18 +575,21 @@
 
 	spin_lock_irqsave(&part->act_lock, irq_flags);
 
-	pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
-
 	DBUG_ON(part->act_state != XPC_P_INACTIVE);
 
-	if (pid > 0) {
-		part->act_state = XPC_P_ACTIVATION_REQ;
-		XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
-	} else {
-		XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
-	}
+	part->act_state = XPC_P_ACTIVATION_REQ;
+	XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
 
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
+
+	pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
+
+	if (unlikely(pid <= 0)) {
+		spin_lock_irqsave(&part->act_lock, irq_flags);
+		part->act_state = XPC_P_INACTIVE;
+		XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
+		spin_unlock_irqrestore(&part->act_lock, irq_flags);
+	}
 }
 
 
diff --git a/arch/ia64/sn/pci/Makefile b/arch/ia64/sn/pci/Makefile
index 321576b..c694678 100644
--- a/arch/ia64/sn/pci/Makefile
+++ b/arch/ia64/sn/pci/Makefile
@@ -7,4 +7,6 @@
 #
 # Makefile for the sn pci general routines.
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/
diff --git a/arch/ia64/sn/pci/pcibr/Makefile b/arch/ia64/sn/pci/pcibr/Makefile
index 1850c4a..3b403ea 100644
--- a/arch/ia64/sn/pci/pcibr/Makefile
+++ b/arch/ia64/sn/pci/pcibr/Makefile
@@ -7,5 +7,7 @@
 #
 # Makefile for the sn2 io routines.
 
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
 obj-y				+=  pcibr_dma.o pcibr_reg.o \
 				    pcibr_ate.o pcibr_provider.o
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index dbc8a39..be8b711 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -18,11 +18,6 @@
 #include <asm/irq.h>
 #include <asm/tlbflush.h>
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
 EXPORT_SYMBOL(dump_fpu);
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index c2e4dcc..d742037 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -37,12 +37,6 @@
 extern void init_mmu(void);
 #endif
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)	\
-	|| defined(CONFIG_BLK_DEV_IDE_MODULE)			\
-	|| defined(CONFIG_BLK_DEV_HD_MODULE)
-struct drive_info_struct { char dummy[32]; } drive_info;
-#endif
-
 extern char _end[];
 
 /*
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 99bf438..63c117d 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -39,6 +39,14 @@
 
 asmlinkage void ret_from_fork(void);
 
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+EXPORT_SYMBOL(pm_idle);
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
 /*
  * The idle loop on an m68knommu..
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index c3e852e..767de84 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -595,6 +595,7 @@
 	select SYS_HAS_CPU_R5000
 	select SYS_HAS_CPU_R10000 if BROKEN
 	select SYS_HAS_CPU_RM7000
+	select SYS_HAS_CPU_NEVADA
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	help
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 2a9f2ef..6a57407 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -53,14 +53,17 @@
 endif
 
 CHECKFLAGS-y				+= -D__linux__ -D__mips__ \
+					   -D_MIPS_SZINT=32 \
 					   -D_ABIO32=1 \
 					   -D_ABIN32=2 \
 					   -D_ABI64=3
 CHECKFLAGS-$(CONFIG_32BIT)		+= -D_MIPS_SIM=_ABIO32 \
 					   -D_MIPS_SZLONG=32 \
+					   -D_MIPS_SZPTR=32 \
 					   -D__PTRDIFF_TYPE__=int
 CHECKFLAGS-$(CONFIG_64BIT)		+= -m64 -D_MIPS_SIM=_ABI64 \
 					   -D_MIPS_SZLONG=64 \
+					   -D_MIPS_SZPTR=64 \
 					   -D__PTRDIFF_TYPE__="long int"
 CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN)	+= -D__MIPSEB__
 CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN)	+= -D__MIPSEL__
@@ -166,79 +169,97 @@
 #
 cflags-$(CONFIG_CPU_R3000)	+= \
 			$(call set_gccflags,r3000,mips1,r3000,mips1,mips1)
+CHECKFLAGS-$(CONFIG_CPU_R3000)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS1
 
 cflags-$(CONFIG_CPU_TX39XX)	+= \
 			$(call set_gccflags,r3900,mips1,r3000,mips1,mips1)
+CHECKFLAGS-$(CONFIG_CPU_TX39XX)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS1
 
 cflags-$(CONFIG_CPU_R6000)	+= \
 			$(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R6000)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS2
 
 cflags-$(CONFIG_CPU_R4300)	+= \
 			$(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R4300)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_VR41XX)	+= \
 			$(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_VR41XX)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_R4X00)	+= \
 			$(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R4X00)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_TX49XX)	+= \
 			$(call set_gccflags,r4600,mips3,r4600,mips3,mips2)  \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_TX49XX)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS3
 
 cflags-$(CONFIG_CPU_MIPS32_R1)	+= \
 			$(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS32_R1)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS32
 
 cflags-$(CONFIG_CPU_MIPS32_R2)	+= \
 			$(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS32_R2)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS32
 
 cflags-$(CONFIG_CPU_MIPS64_R1)	+= \
 			$(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS64_R1)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS64
 
 cflags-$(CONFIG_CPU_MIPS64_R2)	+= \
 			$(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_MIPS64_R2)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS64
 
 cflags-$(CONFIG_CPU_R5000)	+= \
 			$(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R5000)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_R5432)	+= \
 			$(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R5432)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_NEVADA)	+= \
 			$(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \
 			-Wa,--trap
-#			$(call cc-option,-mmad)
+CHECKFLAGS-$(CONFIG_CPU_NEVADA)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_RM7000)	+= \
 			$(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_RM7000)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_RM9000)	+= \
 			$(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_RM9000)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 
 cflags-$(CONFIG_CPU_SB1)	+= \
 			$(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_SB1)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS64
 
 cflags-$(CONFIG_CPU_R8000)	+= \
 			$(call set_gccflags,r8000,mips4,r8000,mips4,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R8000)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 cflags-$(CONFIG_CPU_R10000)	+= \
 			$(call set_gccflags,r10000,mips4,r8000,mips4,mips2) \
 			-Wa,--trap
+CHECKFLAGS-$(CONFIG_CPU_R10000)	+= -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 ifdef CONFIG_CPU_SB1
 ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
@@ -369,7 +390,7 @@
 # Cobalt Server
 #
 core-$(CONFIG_MIPS_COBALT)	+= arch/mips/cobalt/
-cflags-$(CONFIG_MIPS_COBALT)	+= -Iinclude/asm-mips/cobalt
+cflags-$(CONFIG_MIPS_COBALT)	+= -Iinclude/asm-mips/mach-cobalt
 load-$(CONFIG_MIPS_COBALT)	+= 0xffffffff80080000
 
 #
diff --git a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c
index 65b84db..4ffcced 100644
--- a/arch/mips/au1000/common/reset.c
+++ b/arch/mips/au1000/common/reset.c
@@ -151,7 +151,7 @@
 	}
 
 	set_c0_status(ST0_BEV | ST0_ERL);
-	set_c0_config(CONF_CM_UNCACHED);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
 	flush_cache_all();
 	write_c0_wired(0);
 
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 08c8c85..eb155c0 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -125,7 +126,7 @@
 #endif
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
-	_machine_power_off = au1000_power_off;
+	pm_power_off = au1000_power_off;
 	board_time_init = au1xxx_time_init;
 	board_timer_setup = au1xxx_timer_setup;
 
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
index f92608e..e75d5e3 100644
--- a/arch/mips/cobalt/int-handler.S
+++ b/arch/mips/cobalt/int-handler.S
@@ -8,7 +8,7 @@
  */
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
index 0d90851..f9a1088 100644
--- a/arch/mips/cobalt/irq.c
+++ b/arch/mips/cobalt/irq.c
@@ -18,7 +18,7 @@
 #include <asm/gt64120.h>
 #include <asm/ptrace.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 extern void cobalt_handle_int(void);
 
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
index 805a0e8..753dfcc 100644
--- a/arch/mips/cobalt/reset.c
+++ b/arch/mips/cobalt/reset.c
@@ -16,7 +16,7 @@
 #include <asm/reboot.h>
 #include <asm/system.h>
 #include <asm/mipsregs.h>
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 void cobalt_machine_halt(void)
 {
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index 38c0c67..b9713a7 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1996, 1997, 2004, 05 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
  *
  */
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/pm.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 
@@ -25,7 +26,7 @@
 #include <asm/gt64120.h>
 #include <asm/serial.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 extern void cobalt_machine_restart(char *command);
 extern void cobalt_machine_halt(void);
@@ -99,7 +100,7 @@
 
 	_machine_restart = cobalt_machine_restart;
 	_machine_halt = cobalt_machine_halt;
-	_machine_power_off = cobalt_machine_power_off;
+	pm_power_off = cobalt_machine_power_off;
 
 	board_timer_setup = cobalt_timer_setup;
 
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 967e7ac..a34db6e 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -102,6 +102,7 @@
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
 CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_NEVADA=y
 CONFIG_SYS_HAS_CPU_RM7000=y
 CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index dee4460..c02beca 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:00 2005
+# Linux kernel version: 2.6.16-rc2
+# Fri Feb  3 17:14:27 2006
 #
 CONFIG_MIPS=y
 
@@ -147,26 +147,27 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_SYSCTL is not set
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
+CONFIG_ELF_CORE=y
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SHMEM is not set
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -266,11 +267,7 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -323,7 +320,7 @@
 #
 # SCSI device support
 #
-CONFIG_RAID_ATTRS=y
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
@@ -366,24 +363,16 @@
 #
 # PHY device support
 #
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
+# CONFIG_MII is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
@@ -479,6 +468,7 @@
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -518,6 +508,12 @@
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
@@ -592,11 +588,14 @@
 #
 
 #
+# EDAC - error detection and reporting (RAS)
+#
+
+#
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -677,6 +676,7 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -690,31 +690,7 @@
 #
 # Cryptographic options
 #
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_WP512=y
-CONFIG_CRYPTO_TGR192=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_SERPENT=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
-CONFIG_CRYPTO_TEA=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_KHAZAD=y
-CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO is not set
 
 #
 # Hardware crypto devices
@@ -724,8 +700,6 @@
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=y
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c
index 11535be..91456b0 100644
--- a/arch/mips/ddb5xxx/ddb5074/setup.c
+++ b/arch/mips/ddb5xxx/ddb5074/setup.c
@@ -14,6 +14,7 @@
 #include <linux/ide.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
+#include <linux/pm.h>
 
 #include <asm/addrspace.h>
 #include <asm/bcache.h>
@@ -95,7 +96,7 @@
 
 	_machine_restart = ddb_machine_restart;
 	_machine_halt = ddb_machine_halt;
-	_machine_power_off = ddb_machine_power_off;
+	pm_power_off = ddb_machine_power_off;
 
 	ddb_out32(DDB_BAR0, 0);
 
diff --git a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c
index f4e480a..c902ade 100644
--- a/arch/mips/ddb5xxx/ddb5476/setup.c
+++ b/arch/mips/ddb5xxx/ddb5476/setup.c
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
 
 #include <asm/addrspace.h>
 #include <asm/bcache.h>
@@ -133,7 +134,7 @@
 
 	_machine_restart = ddb_machine_restart;
 	_machine_halt = ddb_machine_halt;
-	_machine_power_off = ddb_machine_power_off;
+	pm_power_off = ddb_machine_power_off;
 
 	/* request io port/mem resources  */
 	if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
diff --git a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c
index 8116335..2f56603 100644
--- a/arch/mips/ddb5xxx/ddb5477/setup.c
+++ b/arch/mips/ddb5xxx/ddb5477/setup.c
@@ -26,6 +26,7 @@
 #include <linux/major.h>
 #include <linux/kdev_t.h>
 #include <linux/root_dev.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -182,7 +183,7 @@
 
 	_machine_restart = ddb_machine_restart;
 	_machine_halt = ddb_machine_halt;
-	_machine_power_off = ddb_machine_power_off;
+	pm_power_off = ddb_machine_power_off;
 
 	/* setup resource limits */
 	ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1;
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 9ef54fe..7c1ca8f6 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/pm.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
@@ -158,7 +159,7 @@
 
 	_machine_restart = dec_machine_restart;
 	_machine_halt = dec_machine_halt;
-	_machine_power_off = dec_machine_power_off;
+	pm_power_off = dec_machine_power_off;
 
 	ioport_resource.start = ~0UL;
 	ioport_resource.end = 0UL;
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
index 98b5a96..6d859d1 100644
--- a/arch/mips/gt64120/ev64120/setup.c
+++ b/arch/mips/gt64120/ev64120/setup.c
@@ -34,6 +34,8 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/timex.h>
+#include <linux/pm.h>
+
 #include <asm/bootinfo.h>
 #include <asm/page.h>
 #include <asm/io.h>
@@ -73,7 +75,7 @@
 {
 	_machine_restart = galileo_machine_restart;
 	_machine_halt = galileo_machine_halt;
-	_machine_power_off = galileo_machine_power_off;
+	pm_power_off = galileo_machine_power_off;
 
 	board_time_init = gt64120_time_init;
 	set_io_port_base(KSEG1);
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
index 0d07c33..20b65d3 100644
--- a/arch/mips/gt64120/momenco_ocelot/setup.c
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c
@@ -4,7 +4,7 @@
  * BRIEF MODULE DESCRIPTION
  * Momentum Computer Ocelot (CP7000) - board dependent boot routines
  *
- * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 1996, 1997, 2001, 06  Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2000 RidgeRun, Inc.
  * Copyright (C) 2001 Red Hat, Inc.
  * Copyright (C) 2002 Momentum Computer
@@ -47,6 +47,8 @@
 #include <linux/pci.h>
 #include <linux/timex.h>
 #include <linux/vmalloc.h>
+#include <linux/pm.h>
+
 #include <asm/time.h>
 #include <asm/bootinfo.h>
 #include <asm/page.h>
@@ -159,7 +161,7 @@
 
 	_machine_restart = momenco_ocelot_restart;
 	_machine_halt = momenco_ocelot_halt;
-	_machine_power_off = momenco_ocelot_power_off;
+	pm_power_off = momenco_ocelot_power_off;
 
 	/*
 	 * initrd_start = (ulong)ocelot_initrd_start;
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
index 062429d..fc73c8d 100644
--- a/arch/mips/ite-boards/generic/it8172_setup.c
+++ b/arch/mips/ite-boards/generic/it8172_setup.c
@@ -34,6 +34,7 @@
 #include <linux/major.h>
 #include <linux/kdev_t.h>
 #include <linux/root_dev.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/time.h>
@@ -125,7 +126,7 @@
 
 	_machine_restart = it8172_restart;
 	_machine_halt = it8172_halt;
-	_machine_power_off = it8172_power_off;
+	pm_power_off = it8172_power_off;
 
 	/*
 	 * IO/MEM resources.
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index 044df9d..4036dc4 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -19,6 +19,8 @@
 #include <linux/console.h>
 #include <linux/fb.h>
 #include <linux/ide.h>
+#include <linux/pm.h>
+
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
 #include <asm/jazz.h>
@@ -79,7 +81,7 @@
 
 	_machine_restart = jazz_machine_restart;
 	_machine_halt = jazz_machine_halt;
-	_machine_power_off = jazz_machine_power_off;
+	pm_power_off = jazz_machine_power_off;
 
 #warning "Somebody should check if screen_info is ok for Jazz."
 
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 4763957..9359cc4 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -44,6 +44,7 @@
 #include <linux/ioport.h>
 #include <linux/param.h>	/* for HZ */
 #include <linux/delay.h>
+#include <linux/pm.h>
 #ifdef CONFIG_SERIAL_TXX9
 #include <linux/tty.h>
 #include <linux/serial.h>
@@ -211,7 +212,7 @@
 
 	_machine_restart = jmr3927_machine_restart;
 	_machine_halt = jmr3927_machine_halt;
-	_machine_power_off = jmr3927_machine_power_off;
+	pm_power_off = jmr3927_machine_power_off;
 
 	/*
 	 * IO/MEM resources.
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index fac48ad..292f8b2 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2,8 +2,8 @@
  * Processor capabilities determination functions.
  *
  * Copyright (C) xxxx  the Anonymous
+ * Copyright (C) 1994 - 2006 Ralf Baechle
  * Copyright (C) 2003, 2004  Maciej W. Rozycki
- * Copyright (C) 1994 - 2003 Ralf Baechle
  * Copyright (C) 2001, 2004  MIPS Inc.
  *
  * This program is free software; you can redistribute it and/or
@@ -641,10 +641,9 @@
 	switch (c->processor_id & 0xff00) {
 	case PRID_IMP_SB1:
 		c->cputype = CPU_SB1;
-#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 		/* FPU in pass1 is known to have issues. */
-		c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
-#endif
+		if ((c->processor_id & 0xff) < 0x20)
+			c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
 		break;
 	case PRID_IMP_SB1A:
 		c->cputype = CPU_SB1A;
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index aa18a8b..13f22d1 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -233,11 +233,11 @@
 NESTED(nmi_handler, PT_SIZE, sp)
 	.set	push
 	.set	noat
-	.set	mips3
 	SAVE_ALL
  	move	a0, sp
 	jal	nmi_exception_handler
 	RESTORE_ALL
+	.set	mips3
 	eret
 	.set	pop
 	END(nmi_handler)
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index fa98f10..5232fc7 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -4,6 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others.
+ * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2004 Thiemo Seufer
  */
@@ -58,8 +59,8 @@
 	}
 }
 
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern void do_signal(struct pt_regs *regs);
+extern void do_signal32(struct pt_regs *regs);
 
 /*
  * Native o32 and N64 ABI without DSP ASE
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 0c82b25..0d5cf97 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -88,7 +88,7 @@
 		ret = -EIO;
 		if (copied != sizeof(tmp))
 			break;
-		ret = put_user(tmp, (unsigned int *) (unsigned long) data);
+		ret = put_user(tmp, (unsigned int __user *) (unsigned long) data);
 		break;
 	}
 
@@ -174,8 +174,10 @@
 		case FPC_EIR: {	/* implementation / version register */
 			unsigned int flags;
 
-			if (!cpu_has_fpu)
+			if (!cpu_has_fpu) {
+				tmp = 0;
 				break;
+			}
 
 			preempt_disable();
 			if (cpu_has_mipsmt) {
@@ -194,15 +196,18 @@
 			preempt_enable();
 			break;
 		}
-		case DSP_BASE ... DSP_BASE + 5:
+		case DSP_BASE ... DSP_BASE + 5: {
+			dspreg_t *dregs;
+
 			if (!cpu_has_dsp) {
 				tmp = 0;
 				ret = -EIO;
 				goto out_tsk;
 			}
-			dspreg_t *dregs = __get_dsp_regs(child);
+			dregs = __get_dsp_regs(child);
 			tmp = (unsigned long) (dregs[addr - DSP_BASE]);
 			break;
+		}
 		case DSP_CONTROL:
 			if (!cpu_has_dsp) {
 				tmp = 0;
@@ -216,7 +221,7 @@
 			ret = -EIO;
 			goto out_tsk;
 		}
-		ret = put_user(tmp, (unsigned *) (unsigned long) data);
+		ret = put_user(tmp, (unsigned __user *) (unsigned long) data);
 		break;
 	}
 
@@ -304,15 +309,18 @@
 			else
 				child->thread.fpu.soft.fcr31 = data;
 			break;
-		case DSP_BASE ... DSP_BASE + 5:
+		case DSP_BASE ... DSP_BASE + 5: {
+			dspreg_t *dregs;
+
 			if (!cpu_has_dsp) {
 				ret = -EIO;
 				break;
 			}
 
-			dspreg_t *dregs = __get_dsp_regs(child);
+			dregs = __get_dsp_regs(child);
 			dregs[addr - DSP_BASE] = data;
 			break;
+		}
 		case DSP_CONTROL:
 			if (!cpu_has_dsp) {
 				ret = -EIO;
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c
index 5e37df31..621037d 100644
--- a/arch/mips/kernel/reset.c
+++ b/arch/mips/kernel/reset.c
@@ -3,17 +3,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001 by Ralf Baechle
+ * Copyright (C) 2001, 06 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/pm.h>
 #include <linux/types.h>
 #include <linux/reboot.h>
-#include <asm/reboot.h>
 
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
+#include <asm/reboot.h>
 
 /*
  * Urgs ...  Too many MIPS machines to handle this in a generic way.
@@ -22,23 +21,22 @@
  */
 void (*_machine_restart)(char *command);
 void (*_machine_halt)(void);
-void (*_machine_power_off)(void);
+void (*pm_power_off)(void);
 
 void machine_restart(char *command)
 {
-	_machine_restart(command);
+	if (_machine_restart)
+		_machine_restart(command);
 }
 
 void machine_halt(void)
 {
-	_machine_halt();
+	if (_machine_halt)
+		_machine_halt();
 }
 
 void machine_power_off(void)
 {
 	if (pm_power_off)
 		pm_power_off();
-
-	_machine_power_off();
 }
-
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 1d85511..986a9cf 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2005, 06 Ralf Baechle (ralf@linux-mips.org)
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
@@ -20,9 +21,12 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
+
 #include <asm/mipsmtregs.h>
 #include <asm/bitops.h>
 #include <asm/cpu.h>
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index a42e0e8..d7c4a38 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -617,6 +617,23 @@
 	sys	sys_inotify_init	0
 	sys	sys_inotify_add_watch	3	/* 4285 */
 	sys	sys_inotify_rm_watch	2
+	sys	sys_migrate_pages	4
+	sys	sys_openat		4
+	sys	sys_mkdirat		3
+	sys	sys_mknodat		4	/* 4290 */
+	sys	sys_fchownat		5
+	sys	sys_futimesat		3
+	sys	sys_newfstatat		4
+	sys	sys_unlinkat		3
+	sys	sys_renameat		4	/* 4295 */
+	sys	sys_linkat		4
+	sys	sys_symlinkat		3
+	sys	sys_readlinkat		4
+	sys	sys_fchmodat		3
+	sys	sys_faccessat		3	/* 4300 */
+	sys	sys_pselect6		6
+	sys	sys_ppoll		5
+	sys	sys_unshare		1
 	.endm
 
 	/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 47bfbd4..98bf25d 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -443,3 +443,20 @@
 	PTR	sys_inotify_init
 	PTR	sys_inotify_add_watch
 	PTR	sys_inotify_rm_watch		/* 5245 */
+	PTR	sys_migrate_pages
+	PTR	sys_openat
+	PTR	sys_mkdirat
+	PTR	sys_mknodat
+	PTR	sys_fchownat			/* 5250 */
+	PTR	sys_futimesat
+	PTR	sys_newfstatat
+	PTR	sys_unlinkat
+	PTR	sys_renameat
+	PTR	sys_linkat			/* 5255 */
+	PTR	sys_symlinkat
+	PTR	sys_readlinkat
+	PTR	sys_fchmodat
+	PTR	sys_faccessat
+	PTR	sys_pselect6			/* 5260 */
+	PTR	sys_ppoll
+	PTR	sys_unshare
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index b465ced..bc4980c 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -369,3 +369,20 @@
 	PTR	sys_inotify_init
 	PTR	sys_inotify_add_watch
 	PTR	sys_inotify_rm_watch
+	PTR	sys_migrate_pages		/* 6250 */
+	PTR	sys_openat
+	PTR	sys_mkdirat
+	PTR	sys_mknodat
+	PTR	sys_fchownat
+	PTR	sys_futimesat			/* 6255 */
+	PTR	sys_newfstatat
+	PTR	sys_unlinkat
+	PTR	sys_renameat
+	PTR	sys_linkat
+	PTR	sys_symlinkat			/* 6260 */
+	PTR	sys_readlinkat
+	PTR	sys_fchmodat
+	PTR	sys_faccessat
+	PTR	sys_pselect6
+	PTR	sys_ppoll			/* 6265 */
+	PTR	sys_unshare
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 3d338ca..5b04140 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -491,4 +491,21 @@
 	PTR	sys_inotify_init
 	PTR	sys_inotify_add_watch		/* 4285 */
 	PTR	sys_inotify_rm_watch
+	PTR	sys_migrate_pages
+	PTR	compat_sys_openat
+	PTR	sys_mkdirat
+	PTR	sys_mknodat			/* 4290 */
+	PTR	sys_fchownat
+	PTR	compat_sys_futimesat
+	PTR	compat_sys_newfstatat
+	PTR	sys_unlinkat
+	PTR	sys_renameat			/* 4295 */
+	PTR	sys_linkat
+	PTR	sys_symlinkat
+	PTR	sys_readlinkat
+	PTR	sys_fchmodat
+	PTR	sys_faccessat			/* 4300 */
+	PTR	sys_pselect6
+	PTR	sys_ppoll
+	PTR	sys_unshare
 	.size	sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index 0f66ae58..0fbc492 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -11,7 +11,7 @@
 #include <linux/config.h>
 
 static inline int
-setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
 	int err = 0;
 
@@ -82,7 +82,7 @@
 }
 
 static inline int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
 	unsigned int used_math;
 	unsigned long treg;
@@ -157,7 +157,7 @@
 /*
  * Determine which stack to use..
  */
-static inline void *
+static inline void __user *
 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 {
 	unsigned long sp;
@@ -176,7 +176,7 @@
 	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
-	return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
+	return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
 }
 
 static inline int install_sigtramp(unsigned int __user *tramp,
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 7d1800f..c974cc9 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -39,8 +39,6 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -50,7 +48,7 @@
 __attribute_used__ noinline static int
 _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-	sigset_t saveset, newset;
+	sigset_t newset;
 	sigset_t __user *uset;
 
 	uset = (sigset_t __user *) regs.regs[4];
@@ -59,19 +57,15 @@
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	regs.regs[2] = EINTR;
-	regs.regs[7] = 1;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, &regs))
-			return -EINTR;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 #endif
 
@@ -79,7 +73,7 @@
 __attribute_used__ noinline static int
 _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-	sigset_t saveset, newset;
+	sigset_t newset;
 	sigset_t __user *unewset;
 	size_t sigsetsize;
 
@@ -94,19 +88,15 @@
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	current->blocked = newset;
         recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	regs.regs[2] = EINTR;
-	regs.regs[7] = 1;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, &regs))
-			return -EINTR;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
@@ -199,10 +189,10 @@
 __attribute_used__ noinline static void
 _sys_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-	struct sigframe *frame;
+	struct sigframe __user *frame;
 	sigset_t blocked;
 
-	frame = (struct sigframe *) regs.regs[29];
+	frame = (struct sigframe __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
@@ -236,11 +226,11 @@
 __attribute_used__ noinline static void
 _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-	struct rt_sigframe *frame;
+	struct rt_sigframe __user *frame;
 	sigset_t set;
 	stack_t st;
 
-	frame = (struct rt_sigframe *) regs.regs[29];
+	frame = (struct rt_sigframe __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -259,7 +249,7 @@
 		goto badframe;
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
-	do_sigaltstack(&st, NULL, regs.regs[29]);
+	do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 
 	/*
 	 * Don't let your children do this ...
@@ -279,7 +269,7 @@
 int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set)
 {
-	struct sigframe *frame;
+	struct sigframe __user *frame;
 	int err = 0;
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -315,18 +305,18 @@
 	       current->comm, current->pid,
 	       frame, regs->cp0_epc, frame->regs[31]);
 #endif
-        return 1;
+        return 0;
 
 give_sigsegv:
 	force_sigsegv(signr, current);
-	return 0;
+	return -EFAULT;
 }
 #endif
 
 int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set, siginfo_t *info)
 {
-	struct rt_sigframe *frame;
+	struct rt_sigframe __user *frame;
 	int err = 0;
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -340,7 +330,7 @@
 
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->rs_uc.uc_flags);
-	err |= __put_user(0, &frame->rs_uc.uc_link);
+	err |= __put_user(NULL, &frame->rs_uc.uc_link);
 	err |= __put_user((void *)current->sas_ss_sp,
 	                  &frame->rs_uc.uc_stack.ss_sp);
 	err |= __put_user(sas_ss_flags(regs->regs[29]),
@@ -375,11 +365,11 @@
 	       current->comm, current->pid,
 	       frame, regs->cp0_epc, regs->regs[31]);
 #endif
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(signr, current);
-	return 0;
+	return -EFAULT;
 }
 
 static inline int handle_signal(unsigned long sig, siginfo_t *info,
@@ -393,7 +383,7 @@
 		regs->regs[2] = EINTR;
 		break;
 	case ERESTARTSYS:
-		if(!(ka->sa.sa_flags & SA_RESTART)) {
+		if (!(ka->sa.sa_flags & SA_RESTART)) {
 			regs->regs[2] = EINTR;
 			break;
 		}
@@ -420,9 +410,10 @@
 	return ret;
 }
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
+void do_signal(struct pt_regs *regs)
 {
 	struct k_sigaction ka;
+	sigset_t *oldset;
 	siginfo_t info;
 	int signr;
 
@@ -432,17 +423,31 @@
 	 * if so.
 	 */
 	if (!user_mode(regs))
-		return 1;
+		return;
 
 	if (try_to_freeze())
 		goto no_signal;
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
+
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-	if (signr > 0)
-		return handle_signal(signr, &info, &ka, oldset, regs);
+	if (signr > 0) {
+		/* Whee!  Actually deliver the signal.  */
+		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+			/*
+			 * 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.
+			 */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+	}
 
 no_signal:
 	/*
@@ -463,18 +468,25 @@
 			regs->cp0_epc -= 4;
 		}
 	}
-	return 0;
+
+	/*
+	 * 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);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 }
 
 /*
  * notification of userspace execution resumption
- * - triggered by current->work.notify_resume
+ * - triggered by the TIF_WORK_MASK flags
  */
-asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
+asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
 	__u32 thread_info_flags)
 {
 	/* deal with pending signal delivery */
-	if (thread_info_flags & _TIF_SIGPENDING) {
-		current->thread.abi->do_signal(oldset, regs);
-	}
+	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+		current->thread.abi->do_signal(regs);
 }
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 98b185b..da3271e 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -144,7 +144,7 @@
 extern void __put_sigset_unknown_nsig(void);
 extern void __get_sigset_unknown_nsig(void);
 
-static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf)
+static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
 {
 	int err = 0;
 
@@ -269,7 +269,7 @@
 		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 			return -EFAULT;
 		err |= __get_user(handler, &act->sa_handler);
-		new_ka.sa.sa_handler = (void*)(s64)handler;
+		new_ka.sa.sa_handler = (void __user *)(s64)handler;
 		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 		err |= __get_user(mask, &act->sa_mask.sig[0]);
 		if (err)
@@ -299,8 +299,8 @@
 
 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
 {
-	const stack32_t *uss = (const stack32_t *) regs.regs[4];
-	stack32_t *uoss = (stack32_t *) regs.regs[5];
+	const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
+	stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
 	unsigned long usp = regs.regs[29];
 	stack_t kss, koss;
 	int ret, err = 0;
@@ -319,7 +319,8 @@
 	}
 
 	set_fs (KERNEL_DS);
-	ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp);
+	ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
+			     uoss ? (stack_t __user *)&koss : NULL, usp);
 	set_fs (old_fs);
 
 	if (!ret && uoss) {
@@ -335,7 +336,7 @@
 	return ret;
 }
 
-static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
+static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc)
 {
 	u32 used_math;
 	int err = 0;
@@ -420,7 +421,7 @@
 #endif
 };
 
-int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
 	int err;
 
@@ -455,7 +456,7 @@
 			err |= __put_user(from->si_uid, &to->si_uid);
 			break;
 		case __SI_FAULT >> 16:
-			err |= __put_user((long)from->si_addr, &to->si_addr);
+			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
 			break;
 		case __SI_POLL >> 16:
 			err |= __put_user(from->si_band, &to->si_band);
@@ -476,10 +477,10 @@
 __attribute_used__ noinline static void
 _sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-	struct sigframe *frame;
+	struct sigframe __user *frame;
 	sigset_t blocked;
 
-	frame = (struct sigframe *) regs.regs[29];
+	frame = (struct sigframe __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
@@ -512,13 +513,13 @@
 __attribute_used__ noinline static void
 _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-	struct rt_sigframe32 *frame;
+	struct rt_sigframe32 __user *frame;
 	mm_segment_t old_fs;
 	sigset_t set;
 	stack_t st;
 	s32 sp;
 
-	frame = (struct rt_sigframe32 *) regs.regs[29];
+	frame = (struct rt_sigframe32 __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -546,7 +547,7 @@
 	   call it and ignore errors.  */
 	old_fs = get_fs();
 	set_fs (KERNEL_DS);
-	do_sigaltstack(&st, NULL, regs.regs[29]);
+	do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 	set_fs (old_fs);
 
 	/*
@@ -564,7 +565,7 @@
 }
 
 static inline int setup_sigcontext32(struct pt_regs *regs,
-				     struct sigcontext32 *sc)
+				     struct sigcontext32 __user *sc)
 {
 	int err = 0;
 
@@ -623,8 +624,9 @@
 /*
  * Determine which stack to use..
  */
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-				 size_t frame_size)
+static inline void __user *get_sigframe(struct k_sigaction *ka,
+					struct pt_regs *regs,
+					size_t frame_size)
 {
 	unsigned long sp;
 
@@ -642,13 +644,13 @@
 	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
-	return (void *)((sp - frame_size) & ALMASK);
+	return (void __user *)((sp - frame_size) & ALMASK);
 }
 
 int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set)
 {
-	struct sigframe *frame;
+	struct sigframe __user *frame;
 	int err = 0;
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -692,17 +694,17 @@
 	       current->comm, current->pid,
 	       frame, regs->cp0_epc, frame->sf_code);
 #endif
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(signr, current);
-	return 0;
+	return -EFAULT;
 }
 
 int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set, siginfo_t *info)
 {
-	struct rt_sigframe32 *frame;
+	struct rt_sigframe32 __user *frame;
 	int err = 0;
 	s32 sp;
 
@@ -763,11 +765,11 @@
 	       current->comm, current->pid,
 	       frame, regs->cp0_epc, frame->rs_code);
 #endif
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(signr, current);
-	return 0;
+	return -EFAULT;
 }
 
 static inline int handle_signal(unsigned long sig, siginfo_t *info,
@@ -855,7 +857,7 @@
 }
 
 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
-				  struct sigaction32 *oact,
+				  struct sigaction32 __user *oact,
 				  unsigned int sigsetsize)
 {
 	struct k_sigaction new_sa, old_sa;
@@ -872,7 +874,7 @@
 		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 			return -EFAULT;
 		err |= __get_user(handler, &act->sa_handler);
-		new_sa.sa.sa_handler = (void*)(s64)handler;
+		new_sa.sa.sa_handler = (void __user *)(s64)handler;
 		err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
 		err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
 		if (err)
@@ -899,7 +901,7 @@
 }
 
 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
-	compat_sigset_t *oset, unsigned int sigsetsize)
+	compat_sigset_t __user *oset, unsigned int sigsetsize)
 {
 	sigset_t old_set, new_set;
 	int ret;
@@ -909,8 +911,9 @@
 		return -EFAULT;
 
 	set_fs (KERNEL_DS);
-	ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
-				 oset ? &old_set : NULL, sigsetsize);
+	ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
+				 oset ? (sigset_t __user *)&old_set : NULL,
+				 sigsetsize);
 	set_fs (old_fs);
 
 	if (!ret && oset && put_sigset(&old_set, oset))
@@ -919,7 +922,7 @@
 	return ret;
 }
 
-asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
+asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset,
 	unsigned int sigsetsize)
 {
 	int ret;
@@ -927,7 +930,7 @@
 	mm_segment_t old_fs = get_fs();
 
 	set_fs (KERNEL_DS);
-	ret = sys_rt_sigpending(&set, sigsetsize);
+	ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
 	set_fs (old_fs);
 
 	if (!ret && put_sigset(&set, uset))
@@ -936,7 +939,7 @@
 	return ret;
 }
 
-asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
+asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
 {
 	siginfo_t info;
 	int ret;
@@ -946,7 +949,7 @@
 	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
 		return -EFAULT;
 	set_fs (KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, &info);
+	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
 	set_fs (old_fs);
 	return ret;
 }
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index ec61b26..384fc4a 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -48,6 +48,8 @@
 #define __NR_N32_rt_sigreturn		6211
 #define __NR_N32_restart_syscall	6214
 
+#define DEBUG_SIG 0
+
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 /* IRIX compatible stack_t  */
@@ -83,12 +85,12 @@
 __attribute_used__ noinline static void
 _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-	struct rt_sigframe_n32 *frame;
+	struct rt_sigframe_n32 __user *frame;
 	sigset_t set;
 	stack_t st;
 	s32 sp;
 
-	frame = (struct rt_sigframe_n32 *) regs.regs[29];
+	frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -114,7 +116,7 @@
 
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
-	do_sigaltstack(&st, NULL, regs.regs[29]);
+	do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 
 	/*
 	 * Don't let your children do this ...
@@ -133,7 +135,7 @@
 int setup_rt_frame_n32(struct k_sigaction * ka,
 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
-	struct rt_sigframe_n32 *frame;
+	struct rt_sigframe_n32 __user *frame;
 	int err = 0;
 	s32 sp;
 
@@ -184,9 +186,9 @@
 	       current->comm, current->pid,
 	       frame, regs->cp0_epc, regs->regs[31]);
 #endif
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(signr, current);
-	return 0;
+	return -EFAULT;
 }
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 3323584..1da2eeb 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -212,12 +212,12 @@
 	int error;
 	char * filename;
 
-	filename = getname((char *) (long)regs.regs[4]);
+	filename = getname((char __user *) (long)regs.regs[4]);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename))
 		goto out;
-	error = do_execve(filename, (char **) (long)regs.regs[5],
-	                  (char **) (long)regs.regs[6], &regs);
+	error = do_execve(filename, (char __user *__user *) (long)regs.regs[5],
+	                  (char __user *__user *) (long)regs.regs[6], &regs);
 	putname(filename);
 
 out:
@@ -227,7 +227,7 @@
 /*
  * Compacrapability ...
  */
-asmlinkage int sys_uname(struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname __user * name)
 {
 	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
 		return 0;
@@ -237,7 +237,7 @@
 /*
  * Compacrapability ...
  */
-asmlinkage int sys_olduname(struct oldold_utsname * name)
+asmlinkage int sys_olduname(struct oldold_utsname __user * name)
 {
 	int error;
 
@@ -274,7 +274,7 @@
 asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
 {
 	int	tmp, len;
-	char	*name;
+	char	__user *name;
 
 	switch(cmd) {
 	case SETNAME: {
@@ -283,7 +283,7 @@
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
-		name = (char *) arg1;
+		name = (char __user *) arg1;
 
 		len = strncpy_from_user(nodename, name, __NEW_UTS_LEN);
 		if (len < 0)
@@ -324,7 +324,7 @@
  * This is really horribly ugly.
  */
 asmlinkage int sys_ipc (uint call, int first, int second,
-			unsigned long third, void *ptr, long fifth)
+			unsigned long third, void __user *ptr, long fifth)
 {
 	int version, ret;
 
@@ -333,24 +333,25 @@
 
 	switch (call) {
 	case SEMOP:
-		return sys_semtimedop (first, (struct sembuf *)ptr, second,
-		                       NULL);
+		return sys_semtimedop (first, (struct sembuf __user *)ptr,
+		                       second, NULL);
 	case SEMTIMEDOP:
-		return sys_semtimedop (first, (struct sembuf *)ptr, second,
-		                       (const struct timespec __user *)fifth);
+		return sys_semtimedop (first, (struct sembuf __user *)ptr,
+				       second,
+				       (const struct timespec __user *)fifth);
 	case SEMGET:
 		return sys_semget (first, second, third);
 	case SEMCTL: {
 		union semun fourth;
 		if (!ptr)
 			return -EINVAL;
-		if (get_user(fourth.__pad, (void **) ptr))
+		if (get_user(fourth.__pad, (void *__user *) ptr))
 			return -EFAULT;
 		return sys_semctl (first, second, third, fourth);
 	}
 
 	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf *) ptr,
+		return sys_msgsnd (first, (struct msgbuf __user *) ptr,
 				   second, third);
 	case MSGRCV:
 		switch (version) {
@@ -360,7 +361,7 @@
 				return -EINVAL;
 
 			if (copy_from_user(&tmp,
-					   (struct ipc_kludge *) ptr,
+					   (struct ipc_kludge __user *) ptr,
 					   sizeof (tmp)))
 				return -EFAULT;
 			return sys_msgrcv (first, tmp.msgp, second,
@@ -368,35 +369,38 @@
 		}
 		default:
 			return sys_msgrcv (first,
-					   (struct msgbuf *) ptr,
+					   (struct msgbuf __user *) ptr,
 					   second, fifth, third);
 		}
 	case MSGGET:
 		return sys_msgget ((key_t) first, second);
 	case MSGCTL:
-		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+		return sys_msgctl (first, second,
+				   (struct msqid_ds __user *) ptr);
 
 	case SHMAT:
 		switch (version) {
 		default: {
 			ulong raddr;
-			ret = do_shmat (first, (char *) ptr, second, &raddr);
+			ret = do_shmat (first, (char __user *) ptr, second,
+					&raddr);
 			if (ret)
 				return ret;
-			return put_user (raddr, (ulong *) third);
+			return put_user (raddr, (ulong __user *) third);
 		}
 		case 1:	/* iBCS2 emulator entry point */
 			if (!segment_eq(get_fs(), get_ds()))
 				return -EINVAL;
-			return do_shmat (first, (char *) ptr, second, (ulong *) third);
+			return do_shmat (first, (char __user *) ptr, second,
+					 (ulong *) third);
 		}
 	case SHMDT:
-		return sys_shmdt ((char *)ptr);
+		return sys_shmdt ((char __user *)ptr);
 	case SHMGET:
 		return sys_shmget (first, second, third);
 	case SHMCTL:
 		return sys_shmctl (first, second,
-				   (struct shmid_ds *) ptr);
+				   (struct shmid_ds __user *) ptr);
 	default:
 		return -ENOSYS;
 	}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 59a1879..c9d2b51 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1168,7 +1168,7 @@
 #endif
 	if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
 		status_set |= ST0_XX;
-	change_c0_status(ST0_CU|ST0_MX|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
+	change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
 			 status_set);
 
 	if (cpu_has_dsp)
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 25cc856..ff699db 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -1,4 +1,5 @@
 #include <linux/config.h>
+#include <asm/asm-offsets.h>
 #include <asm-generic/vmlinux.lds.h>
 
 #undef mips		/* CPP really sucks for this job  */
@@ -64,10 +65,10 @@
      we can shorten the on-disk segment size.  */
   .sdata     : { *(.sdata) }
 
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __nosave_begin = .;
   .data_nosave : { *(.data.nosave) }
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __nosave_end = .;
 
   . = ALIGN(32);
@@ -76,7 +77,7 @@
   _edata =  .;			/* End of data section */
 
   /* will be freed after init */
-  . = ALIGN(4096);		/* Init code and data */
+  . = ALIGN(_PAGE_SIZE);		/* Init code and data */
   __init_begin = .;
   .init.text : {
 	_sinittext = .;
@@ -105,7 +106,7 @@
   .con_initcall.init : { *(.con_initcall.init) }
   __con_initcall_end = .;
   SECURITY_INIT
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __initramfs_start = .;
   .init.ramfs : { *(.init.ramfs) }
   __initramfs_end = .;
@@ -113,7 +114,7 @@
   __per_cpu_start = .;
   .data.percpu  : { *(.data.percpu) }
   __per_cpu_end = .;
-  . = ALIGN(4096);
+  . = ALIGN(_PAGE_SIZE);
   __init_end = .;
   /* freed after init ends here */
 
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c
index 8d7d7a4..181bf68 100644
--- a/arch/mips/lasat/reset.c
+++ b/arch/mips/lasat/reset.c
@@ -19,9 +19,12 @@
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/pm.h>
+
 #include <asm/reboot.h>
 #include <asm/system.h>
 #include <asm/lasat/lasat.h>
+
 #include "picvue.h"
 #include "prom.h"
 
@@ -63,5 +66,5 @@
 {
 	_machine_restart = lasat_machine_restart;
 	_machine_halt = lasat_machine_halt;
-	_machine_power_off = lasat_machine_halt;
+	pm_power_off = lasat_machine_halt;
 }
diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
index 46519f4..c49a925 100644
--- a/arch/mips/lib-32/dump_tlb.c
+++ b/arch/mips/lib-32/dump_tlb.c
@@ -158,29 +158,26 @@
 	printk("task->mm             == %8p\n", t->mm);
 	//printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
 
-	if (addr > KSEG0)
+	if (addr > KSEG0) {
 		page_dir = pgd_offset_k(0);
-	else if (t->mm) {
-		page_dir = pgd_offset(t->mm, 0);
-		printk("page_dir == %08x\n", (unsigned int) page_dir);
-	} else
-		printk("Current thread has no mm\n");
-
-	if (addr > KSEG0)
 		pgd = pgd_offset_k(addr);
-	else if (t->mm) {
+	} else if (t->mm) {
+		page_dir = pgd_offset(t->mm, 0);
 		pgd = pgd_offset(t->mm, addr);
-		printk("pgd == %08x, ", (unsigned int) pgd);
-		pud = pud_offset(pgd, addr);
-		printk("pud == %08x, ", (unsigned int) pud);
-
-		pmd = pmd_offset(pud, addr);
-		printk("pmd == %08x, ", (unsigned int) pmd);
-
-		pte = pte_offset(pmd, addr);
-		printk("pte == %08x, ", (unsigned int) pte);
-	} else
+	} else {
 		printk("Current thread has no mm\n");
+		return;
+	}
+	printk("page_dir == %08x\n", (unsigned int) page_dir);
+	printk("pgd == %08x, ", (unsigned int) pgd);
+	pud = pud_offset(pgd, addr);
+	printk("pud == %08x, ", (unsigned int) pud);
+
+	pmd = pmd_offset(pud, addr);
+	printk("pmd == %08x, ", (unsigned int) pmd);
+
+	pte = pte_offset(pmd, addr);
+	printk("pte == %08x, ", (unsigned int) pte);
 
 	page = *pte;
 #ifdef CONFIG_64BIT_PHYS_ADDR
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
index 495c1ac..1c555e6 100644
--- a/arch/mips/math-emu/dp_simple.c
+++ b/arch/mips/math-emu/dp_simple.c
@@ -48,16 +48,22 @@
 	CLEARCX;
 	FLUSHXDP;
 
+	/*
+	 * Invert the sign ALWAYS to prevent an endless recursion on
+	 * pow() in libc.
+	 */
+	/* quick fix up */
+	DPSIGN(x) ^= 1;
+
 	if (xc == IEEE754_CLASS_SNAN) {
+		ieee754dp y = ieee754dp_indef();
 		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
+		DPSIGN(y) = DPSIGN(x);
+		return ieee754dp_nanxcpt(y, "neg");
 	}
 
 	if (ieee754dp_isnan(x))	/* but not infinity */
 		return ieee754dp_nanxcpt(x, "neg", x);
-
-	/* quick fix up */
-	DPSIGN(x) ^= 1;
 	return x;
 }
 
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
index c809830..770f0f4 100644
--- a/arch/mips/math-emu/sp_simple.c
+++ b/arch/mips/math-emu/sp_simple.c
@@ -48,16 +48,22 @@
 	CLEARCX;
 	FLUSHXSP;
 
+	/*
+	 * Invert the sign ALWAYS to prevent an endless recursion on
+	 * pow() in libc.
+	 */
+	/* quick fix up */
+	SPSIGN(x) ^= 1;
+
 	if (xc == IEEE754_CLASS_SNAN) {
+		ieee754sp y = ieee754sp_indef();
 		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_nanxcpt(ieee754sp_indef(), "neg");
+		SPSIGN(y) = SPSIGN(x);
+		return ieee754sp_nanxcpt(y, "neg");
 	}
 
 	if (ieee754sp_isnan(x))	/* but not infinity */
 		return ieee754sp_nanxcpt(x, "neg", x);
-
-	/* quick fix up */
-	SPSIGN(x) ^= 1;
 	return x;
 }
 
diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c
index 9fdec74..7213c39 100644
--- a/arch/mips/mips-boards/generic/reset.c
+++ b/arch/mips/mips-boards/generic/reset.c
@@ -23,6 +23,7 @@
  *
  */
 #include <linux/config.h>
+#include <linux/pm.h>
 
 #include <asm/io.h>
 #include <asm/reboot.h>
@@ -65,9 +66,9 @@
 	_machine_restart = mips_machine_restart;
 	_machine_halt = mips_machine_halt;
 #if defined(CONFIG_MIPS_ATLAS)
-	_machine_power_off = atlas_machine_power_off;
+	pm_power_off = atlas_machine_power_off;
 #endif
 #if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD)
-	_machine_power_off = mips_machine_halt;
+	pm_power_off = mips_machine_halt;
 #endif
 }
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 422b55f..e51c38c 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -464,8 +464,8 @@
 }
 
 struct flush_icache_range_args {
-	unsigned long __user start;
-	unsigned long __user end;
+	unsigned long start;
+	unsigned long end;
 };
 
 static inline void local_r4k_flush_icache_range(void *args)
@@ -528,8 +528,7 @@
 	}
 }
 
-static void r4k_flush_icache_range(unsigned long __user start,
-	unsigned long __user end)
+static void r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
 	struct flush_icache_range_args args;
 
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 314701a..591c22b 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -25,8 +25,7 @@
 	unsigned long end);
 void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
 	unsigned long pfn);
-void (*flush_icache_range)(unsigned long __user start,
-	unsigned long __user end);
+void (*flush_icache_range)(unsigned long start, unsigned long end);
 void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
 
 /* MIPS specific cache operations */
@@ -53,7 +52,7 @@
  * We could optimize the case where the cache argument is not BCACHE but
  * that seems very atypical use ...
  */
-asmlinkage int sys_cacheflush(unsigned long __user addr,
+asmlinkage int sys_cacheflush(unsigned long addr,
 	unsigned long bytes, unsigned int cache)
 {
 	if (bytes == 0)
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 4ee91c9..0ff9a34 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -24,6 +24,7 @@
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
+#include <linux/proc_fs.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
@@ -200,6 +201,11 @@
 	return 0;
 }
 
+static struct kcore_list kcore_mem, kcore_vmalloc;
+#ifdef CONFIG_64BIT
+static struct kcore_list kcore_kseg0;
+#endif
+
 void __init mem_init(void)
 {
 	unsigned long codesize, reservedpages, datasize, initsize;
@@ -249,6 +255,16 @@
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
+#ifdef CONFIG_64BIT
+	if ((unsigned long) &_text > (unsigned long) CKSEG0)
+		/* The -4 is a hack so that user tools don't have to handle
+		   the overflow.  */
+		kclist_add(&kcore_kseg0, (void *) CKSEG0, 0x80000000 - 4);
+#endif
+	kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
+	kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
+		   VMALLOC_END-VMALLOC_START);
+
 	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
 	       "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
 	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
index bab192d..301d672 100644
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -50,6 +50,7 @@
 #include <linux/pci.h>
 #include <linux/swap.h>
 #include <linux/ioport.h>
+#include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
@@ -365,7 +366,7 @@
 
 	_machine_restart = momenco_jaguar_restart;
 	_machine_halt = momenco_jaguar_halt;
-	_machine_power_off = momenco_jaguar_power_off;
+	pm_power_off = momenco_jaguar_power_off;
 
 	/*
 	 * initrd_start = (ulong)jaguar_initrd_start;
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index c9b7ff8..f95677f 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -57,6 +57,8 @@
 #include <linux/timex.h>
 #include <linux/bootmem.h>
 #include <linux/mv643xx.h>
+#include <linux/pm.h>
+
 #include <asm/time.h>
 #include <asm/page.h>
 #include <asm/bootinfo.h>
@@ -321,7 +323,7 @@
 
 	_machine_restart = momenco_ocelot_restart;
 	_machine_halt = momenco_ocelot_halt;
-	_machine_power_off = momenco_ocelot_power_off;
+	pm_power_off = momenco_ocelot_power_off;
 
 	/* Wired TLB entries */
 	setup_wired_tlb_entries();
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index 2755c15..15998d8 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -51,8 +51,10 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
 #include <linux/timex.h>
 #include <linux/vmalloc.h>
+
 #include <asm/time.h>
 #include <asm/bootinfo.h>
 #include <asm/page.h>
@@ -236,7 +238,7 @@
 
 	_machine_restart = momenco_ocelot_restart;
 	_machine_halt = momenco_ocelot_halt;
-	_machine_power_off = momenco_ocelot_power_off;
+	pm_power_off = momenco_ocelot_power_off;
 
 	/*
 	 * initrd_start = (ulong)ocelot_initrd_start;
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
index 6336751..fed4e8e 100644
--- a/arch/mips/momentum/ocelot_g/setup.c
+++ b/arch/mips/momentum/ocelot_g/setup.c
@@ -47,8 +47,10 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
 #include <linux/timex.h>
 #include <linux/vmalloc.h>
+
 #include <asm/time.h>
 #include <asm/bootinfo.h>
 #include <asm/page.h>
@@ -169,7 +171,7 @@
 
 	_machine_restart = momenco_ocelot_restart;
 	_machine_halt = momenco_ocelot_halt;
-	_machine_power_off = momenco_ocelot_power_off;
+	pm_power_off = momenco_ocelot_power_off;
 
 	/*
 	 * initrd_start = (ulong)ocelot_initrd_start;
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
index 354261d..0a50aad 100644
--- a/arch/mips/oprofile/Makefile
+++ b/arch/mips/oprofile/Makefile
@@ -12,4 +12,5 @@
 
 oprofile-$(CONFIG_CPU_MIPS32)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_SB1)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index 53f9889..935dd85 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -79,6 +79,9 @@
 	case CPU_20KC:
 	case CPU_24K:
 	case CPU_25KF:
+	case CPU_34K:
+	case CPU_SB1:
+	case CPU_SB1A:
 		lmodel = &op_model_mipsxx;
 		break;
 
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 1d1eee4..95d488c 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -201,10 +201,21 @@
 		op_model_mipsxx.cpu_type = "mips/25K";
 		break;
 
+#ifndef CONFIG_SMP
+	case CPU_34K:
+		op_model_mipsxx.cpu_type = "mips/34K";
+		break;
+#endif
+
 	case CPU_5KC:
 		op_model_mipsxx.cpu_type = "mips/5K";
 		break;
 
+	case CPU_SB1:
+	case CPU_SB1A:
+		op_model_mipsxx.cpu_type = "mips/sb1";
+		break;
+
 	default:
 		printk(KERN_ERR "Profiling unsupported for this CPU\n");
 
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 741e67c..16205b5 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -46,6 +46,7 @@
 obj-$(CONFIG_SGI_IP27)		+= pci-ip27.o
 obj-$(CONFIG_SGI_IP32)		+= fixup-ip32.o ops-mace.o pci-ip32.o
 obj-$(CONFIG_SIBYTE_SB1250)	+= fixup-sb1250.o pci-sb1250.o
+obj-$(CONFIG_SIBYTE_BCM112X)	+= fixup-sb1250.o pci-sb1250.o
 obj-$(CONFIG_SIBYTE_BCM1x80)	+= pci-bcm1480.o pci-bcm1480ht.o
 obj-$(CONFIG_SNI_RM200_PCI)	+= fixup-sni.o ops-sni.o
 obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index 909292f..75a01e7 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -17,7 +17,7 @@
 #include <asm/io.h>
 #include <asm/gt64120.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 extern int cobalt_board_id;
 
@@ -52,7 +52,7 @@
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lt);
 	if (lt < 64)
 		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
@@ -69,7 +69,7 @@
 	 * host bridge.
 	 */
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
 
 	/*
 	 * The code described by the comment below has been removed
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c
index c180793..13de459 100644
--- a/arch/mips/pci/ops-gt64111.c
+++ b/arch/mips/pci/ops-gt64111.c
@@ -15,7 +15,7 @@
 #include <asm/io.h>
 #include <asm/gt64120.h>
 
-#include <asm/cobalt/cobalt.h>
+#include <asm/mach-cobalt/cobalt.h>
 
 /*
  * Device 31 on the GT64111 is used to generate PCI special
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
index f194b4e..ca975e7 100644
--- a/arch/mips/pci/pci-bcm1480.c
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -234,11 +234,9 @@
 
 	/* turn on ExpMemEn */
 	cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
-	printk("PCIFeatureCtrl = %x\n", cmdreg);
 	WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40),
 			cmdreg | 0x10);
 	cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
-	printk("PCIFeatureCtrl = %x\n", cmdreg);
 
 	/*
 	 * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c
index ee6bf72..0d8a776 100644
--- a/arch/mips/philips/pnx8550/common/setup.c
+++ b/arch/mips/philips/pnx8550/common/setup.c
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/serial_ip3106.h>
+#include <linux/pm.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -90,7 +91,7 @@
 
         _machine_restart = pnx8550_machine_restart;
         _machine_halt = pnx8550_machine_halt;
-        _machine_power_off = pnx8550_machine_power_off;
+        pm_power_off = pnx8550_machine_power_off;
 
 	board_time_init = pnx8550_time_init;
 	board_timer_setup = pnx8550_timer_setup;
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
index 555bfacf..165275c 100644
--- a/arch/mips/pmc-sierra/yosemite/prom.c
+++ b/arch/mips/pmc-sierra/yosemite/prom.c
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
+#include <linux/pm.h>
 #include <linux/smp.h>
 
 #include <asm/io.h>
@@ -92,7 +93,7 @@
 	/* Callbacks for halt, restart */
 	_machine_restart = (void (*)(char *)) prom_exit;
 	_machine_halt = prom_halt;
-	_machine_power_off = prom_halt;
+	pm_power_off = prom_halt;
 
 	debug_vectors = cv;
 	arcs_cmdline[0] = '\0';
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 214ffd2..92a3b3c 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -3,8 +3,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998, 2001, 2003 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 2001, 03, 05, 06 by Ralf Baechle
  */
+#include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/ds1286.h>
 #include <linux/module.h>
@@ -12,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
+#include <linux/pm.h>
 #include <linux/timer.h>
 
 #include <asm/io.h>
@@ -41,28 +43,10 @@
 
 #define MACHINE_PANICED		1
 #define MACHINE_SHUTTING_DOWN	2
-static int machine_state = 0;
 
-static void sgi_machine_restart(char *command) __attribute__((noreturn));
-static void sgi_machine_halt(void) __attribute__((noreturn));
-static void sgi_machine_power_off(void) __attribute__((noreturn));
+static int machine_state;
 
-static void sgi_machine_restart(char *command)
-{
-	if (machine_state & MACHINE_SHUTTING_DOWN)
-		sgi_machine_power_off();
-	sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
-	while (1);
-}
-
-static void sgi_machine_halt(void)
-{
-	if (machine_state & MACHINE_SHUTTING_DOWN)
-		sgi_machine_power_off();
-	ArcEnterInteractiveMode();
-}
-
-static void sgi_machine_power_off(void)
+static void ATTRIB_NORET sgi_machine_power_off(void)
 {
 	unsigned int tmp;
 
@@ -84,6 +68,21 @@
 	}
 }
 
+static void ATTRIB_NORET sgi_machine_restart(char *command)
+{
+	if (machine_state & MACHINE_SHUTTING_DOWN)
+		sgi_machine_power_off();
+	sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
+	while (1);
+}
+
+static void ATTRIB_NORET sgi_machine_halt(void)
+{
+	if (machine_state & MACHINE_SHUTTING_DOWN)
+		sgi_machine_power_off();
+	ArcEnterInteractiveMode();
+}
+
 static void power_timeout(unsigned long data)
 {
 	sgi_machine_power_off();
@@ -95,7 +94,7 @@
 	sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF);
 	sgioc->reset = sgi_ioc_reset;
 
-	mod_timer(&blink_timer, jiffies+data);
+	mod_timer(&blink_timer, jiffies + data);
 }
 
 static void debounce(unsigned long data)
@@ -103,7 +102,7 @@
 	del_timer(&debounce_timer);
 	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
 		/* Interrupt still being sent. */
-		debounce_timer.expires = jiffies + 5; /* 0.05s  */
+		debounce_timer.expires = jiffies + (HZ / 20); /* 0.05s  */
 		add_timer(&debounce_timer);
 
 		sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR |
@@ -151,7 +150,7 @@
 		indy_volume_button(1);
 
 	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
-		volume_timer.expires = jiffies + 1;
+		volume_timer.expires = jiffies + (HZ / 100);
 		add_timer(&volume_timer);
 	}
 }
@@ -164,7 +163,7 @@
 		indy_volume_button(-1);
 
 	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
-		volume_timer.expires = jiffies + 1;
+		volume_timer.expires = jiffies + (HZ / 100);
 		add_timer(&volume_timer);
 	}
 }
@@ -199,14 +198,14 @@
 	if (!(buttons & SGIOC_PANEL_VOLUPINTR)) {
 		init_timer(&volume_timer);
 		volume_timer.function = volume_up_button;
-		volume_timer.expires = jiffies + 1;
+		volume_timer.expires = jiffies + (HZ / 100);
 		add_timer(&volume_timer);
 	}
 	/* Volume down button was pressed */
 	if (!(buttons & SGIOC_PANEL_VOLDNINTR)) {
 		init_timer(&volume_timer);
 		volume_timer.function = volume_down_button;
-		volume_timer.expires = jiffies + 1;
+		volume_timer.expires = jiffies + (HZ / 100);
 		add_timer(&volume_timer);
 	}
 
@@ -234,7 +233,7 @@
 {
 	_machine_restart = sgi_machine_restart;
 	_machine_halt = sgi_machine_halt;
-	_machine_power_off = sgi_machine_power_off;
+	pm_power_off = sgi_machine_power_off;
 
 	request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
 	init_timer(&blink_timer);
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index 5e59b4c..7018e18 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -56,6 +56,7 @@
 void __init plat_setup(void)
 {
 	char *ctype;
+	char *cserial;
 
 	board_be_init = ip22_be_init;
 	ip22_time_init();
@@ -81,9 +82,14 @@
 	/* ARCS console environment variable is set to "g?" for
 	 * graphics console, it is set to "d" for the first serial
 	 * line and "d2" for the second serial line.
+	 *
+	 * Need to check if the case is 'g' but no keyboard:
+	 * (ConsoleIn/Out = serial)
 	 */
 	ctype = ArcGetEnvironmentVariable("console");
-	if (ctype && *ctype == 'd') {
+	cserial = ArcGetEnvironmentVariable("ConsoleOut");
+
+	if ((ctype && *ctype == 'd') || (cserial && *cserial == 's')) {
 		static char options[8];
 		char *baud = ArcGetEnvironmentVariable("dbaud");
 		if (baud)
@@ -91,7 +97,7 @@
 		add_preferred_console("ttyS", *(ctype + 1) == '2' ? 1 : 0,
 				      baud ? options : NULL);
 	} else if (!ctype || *ctype != 'g') {
-		/* Use ARC if we don't want serial ('d') or Newport ('g'). */
+		/* Use ARC if we don't want serial ('d') or graphics ('g'). */
 		prom_flags |= PROM_FLAG_USE_AS_CONSOLE;
 		add_preferred_console("arc", 0, NULL);
 	}
diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c
index 2e16be9..4322db5 100644
--- a/arch/mips/sgi-ip27/ip27-reset.c
+++ b/arch/mips/sgi-ip27/ip27-reset.c
@@ -5,7 +5,7 @@
  *
  * Reset an IP27.
  *
- * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999, 2000, 06 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
@@ -15,6 +15,7 @@
 #include <linux/smp.h>
 #include <linux/mmzone.h>
 #include <linux/nodemask.h>
+#include <linux/pm.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -77,5 +78,5 @@
 {
 	_machine_restart = ip27_machine_restart;
 	_machine_halt = ip27_machine_halt;
-	_machine_power_off = ip27_machine_power_off;
+	pm_power_off = ip27_machine_power_off;
 }
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 88e1f52..0c94800 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/ds17287rtc.h>
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 
 #include <asm/addrspace.h>
 #include <asm/irq.h>
@@ -188,7 +189,7 @@
 
 	_machine_restart = ip32_machine_restart;
 	_machine_halt = ip32_machine_halt;
-	_machine_power_off = ip32_machine_power_off;
+	pm_power_off = ip32_machine_power_off;
 
 	init_timer(&blink_timer);
 	blink_timer.function = blink_timeout;
diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c
index 7a2c7a8..ea30802 100644
--- a/arch/mips/sibyte/cfe/setup.c
+++ b/arch/mips/sibyte/cfe/setup.c
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>
+#include <linux/pm.h>
 #include <linux/smp.h>
 
 #include <asm/bootinfo.h>
@@ -248,7 +249,7 @@
 
 	_machine_restart   = cfe_linux_restart;
 	_machine_halt      = cfe_linux_halt;
-	_machine_power_off = cfe_linux_halt;
+	pm_power_off = cfe_linux_halt;
 
 	/*
 	 * Check if a loader was used; if NOT, the 4 arguments are
diff --git a/arch/mips/sibyte/sb1250/prom.c b/arch/mips/sibyte/sb1250/prom.c
index de62ab0..742043f 100644
--- a/arch/mips/sibyte/sb1250/prom.c
+++ b/arch/mips/sibyte/sb1250/prom.c
@@ -24,6 +24,7 @@
 #include <linux/bootmem.h>
 #include <linux/smp.h>
 #include <linux/initrd.h>
+#include <linux/pm.h>
 
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
@@ -79,7 +80,7 @@
 {
 	_machine_restart   = (void (*)(char *))prom_linux_exit;
 	_machine_halt      = prom_linux_exit;
-	_machine_power_off = prom_linux_exit;
+	pm_power_off = prom_linux_exit;
 
 	strcpy(arcs_cmdline, "root=/dev/ram0 ");
 
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
index df2e266..fde4751 100644
--- a/arch/mips/sibyte/sb1250/setup.c
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/string.h>
@@ -42,7 +43,7 @@
 
 /* Setup code likely to be common to all SiByte platforms */
 
-static inline int sys_rev_decode(void)
+static int __init sys_rev_decode(void)
 {
 	int ret = 0;
 
@@ -74,7 +75,7 @@
 	return ret;
 }
 
-static inline int setup_bcm1250(void)
+static int __init setup_bcm1250(void)
 {
 	int ret = 0;
 
@@ -120,7 +121,7 @@
 	return ret;
 }
 
-static inline int setup_bcm112x(void)
+static int __init setup_bcm112x(void)
 {
 	int ret = 0;
 
@@ -146,7 +147,7 @@
 	return ret;
 }
 
-void sb1250_setup(void)
+void __init sb1250_setup(void)
 {
 	uint64_t sys_rev;
 	int plldiv;
@@ -169,31 +170,42 @@
 		    soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
 	prom_printf("Board type: %s\n", get_system_type());
 
-	switch(war_pass) {
+	switch (war_pass) {
 	case K_SYS_REVISION_BCM1250_PASS1:
 #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
-		prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+		prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, "
+		            "and the kernel doesn't have the proper "
+		            "workarounds compiled in. @@@@\n");
 		bad_config = 1;
 #endif
 		break;
 	case K_SYS_REVISION_BCM1250_PASS2:
 		/* Pass 2 - easiest as default for now - so many numbers */
-#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
-		prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \
+    !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
+		prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the "
+		            "kernel doesn't have the proper workarounds "
+		            "compiled in. @@@@\n");
 		bad_config = 1;
 #endif
 #ifdef CONFIG_CPU_HAS_PREFETCH
-		prom_printf("@@@@ Prefetches may be enabled in this kernel, but are buggy on this board.  @@@@\n");
+		prom_printf("@@@@ Prefetches may be enabled in this kernel, "
+		            "but are buggy on this board.  @@@@\n");
 		bad_config = 1;
 #endif
 		break;
 	case K_SYS_REVISION_BCM1250_PASS2_2:
 #ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
-		prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+		prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the "
+		            "kernel doesn't have the proper workarounds "
+		            "compiled in. @@@@\n");
 		bad_config = 1;
 #endif
-#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || !defined(CONFIG_CPU_HAS_PREFETCH)
-		prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n");
+#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \
+    !defined(CONFIG_CPU_HAS_PREFETCH)
+		prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is "
+		            "conservatively configured for an 'A' stepping. "
+		            "@@@@\n");
 #endif
 		break;
 	default:
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 262c856..1141fcd 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 97, 98, 2000, 03, 04 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
  */
 #include <linux/config.h>
 #include <linux/eisa.h>
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
+#include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/console.h>
 #include <linux/fb.h>
@@ -189,7 +190,7 @@
 
 	_machine_restart = sni_machine_restart;
 	_machine_halt = sni_machine_halt;
-	_machine_power_off = sni_machine_power_off;
+	pm_power_off = sni_machine_power_off;
 
 	sni_display_setup();
 
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c
index e4d095d..e19e2be 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c
@@ -60,7 +60,6 @@
 
 void __init prom_init(void)
 {
-	const char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES;
 	extern int tx4927_get_mem_size(void);
 	extern char* toshiba_name;
 	int msize;
@@ -69,12 +68,13 @@
 
 	mips_machgroup = MACH_GROUP_TOSHIBA;
 
-	if ((read_c0_prid() & 0xff) == PRID_REV_TX4927)
+	if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) {
 		mips_machtype = MACH_TOSHIBA_RBTX4927;
-	else
+ 		toshiba_name  = "TX4927";
+	} else {
 		mips_machtype = MACH_TOSHIBA_RBTX4937;
-
-        toshiba_name = toshiba_name_list[mips_machtype];
+ 		toshiba_name  = "TX4937";
+	}
 
 	msize = tx4927_get_mem_size();
 	add_memory_region(0, msize << 20, BOOT_MEM_RAM);
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 990fcb2..2ad6401 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -53,6 +53,8 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/timex.h>
+#include <linux/pm.h>
+
 #include <asm/bootinfo.h>
 #include <asm/page.h>
 #include <asm/io.h>
@@ -537,19 +539,10 @@
 	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
 				       "0x%08lx=mips_io_port_base",
 				       mips_io_port_base);
-
-	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
-				       "setup pci_io_resource  to 0x%08lx 0x%08lx\n",
-				       pci_io_resource.start,
-				       pci_io_resource.end);
-	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
-				       "setup pci_mem_resource to 0x%08lx 0x%08lx\n",
-				       pci_mem_resource.start,
-				       pci_mem_resource.end);
-
 	if (!called) {
 		printk
-		    ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+		    ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+		     toshiba_name,
 		     (unsigned short) (tx4927_pcicptr->pciid >> 16),
 		     (unsigned short) (tx4927_pcicptr->pciid & 0xffff),
 		     (unsigned short) (tx4927_pcicptr->pciccrev & 0xff),
@@ -562,21 +555,52 @@
 	       (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : "");
 	if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) {
 		int pciclk = 0;
-		switch ((unsigned long) tx4927_ccfgptr->
-			ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
-		case TX4927_CCFG_PCIDIVMODE_2_5:
-			pciclk = tx4927_cpu_clock * 2 / 5;
-			break;
-		case TX4927_CCFG_PCIDIVMODE_3:
-			pciclk = tx4927_cpu_clock / 3;
-			break;
-		case TX4927_CCFG_PCIDIVMODE_5:
-			pciclk = tx4927_cpu_clock / 5;
-			break;
-		case TX4927_CCFG_PCIDIVMODE_6:
-			pciclk = tx4927_cpu_clock / 6;
-			break;
-		}
+		if (mips_machtype == MACH_TOSHIBA_RBTX4937)
+			switch ((unsigned long) tx4927_ccfgptr->
+				ccfg & TX4937_CCFG_PCIDIVMODE_MASK) {
+			case TX4937_CCFG_PCIDIVMODE_4:
+				pciclk = tx4927_cpu_clock / 4;
+				break;
+			case TX4937_CCFG_PCIDIVMODE_4_5:
+				pciclk = tx4927_cpu_clock * 2 / 9;
+				break;
+			case TX4937_CCFG_PCIDIVMODE_5:
+				pciclk = tx4927_cpu_clock / 5;
+				break;
+			case TX4937_CCFG_PCIDIVMODE_5_5:
+				pciclk = tx4927_cpu_clock * 2 / 11;
+				break;
+			case TX4937_CCFG_PCIDIVMODE_8:
+				pciclk = tx4927_cpu_clock / 8;
+				break;
+			case TX4937_CCFG_PCIDIVMODE_9:
+				pciclk = tx4927_cpu_clock / 9;
+				break;
+			case TX4937_CCFG_PCIDIVMODE_10:
+				pciclk = tx4927_cpu_clock / 10;
+				break;
+			case TX4937_CCFG_PCIDIVMODE_11:
+				pciclk = tx4927_cpu_clock / 11;
+				break;
+			}
+
+		else
+			switch ((unsigned long) tx4927_ccfgptr->
+				ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
+			case TX4927_CCFG_PCIDIVMODE_2_5:
+				pciclk = tx4927_cpu_clock * 2 / 5;
+				break;
+			case TX4927_CCFG_PCIDIVMODE_3:
+				pciclk = tx4927_cpu_clock / 3;
+				break;
+			case TX4927_CCFG_PCIDIVMODE_5:
+				pciclk = tx4927_cpu_clock / 5;
+				break;
+			case TX4927_CCFG_PCIDIVMODE_6:
+				pciclk = tx4927_cpu_clock / 6;
+				break;
+			}
+
 		printk("Internal(%dMHz)", pciclk / 1000000);
 	} else {
 		int pciclk = 0;
@@ -814,24 +838,40 @@
 				       ":ResetRoutines\n");
 	_machine_restart = toshiba_rbtx4927_restart;
 	_machine_halt = toshiba_rbtx4927_halt;
-	_machine_power_off = toshiba_rbtx4927_power_off;
+	pm_power_off = toshiba_rbtx4927_power_off;
 
 #ifdef CONFIG_PCI
 
 	/* PCIC */
 	/*
 	   * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
-	   * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1).
+	   *
+	   * For TX4927:
+	   * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1).
 	   * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
 	   * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
 	   * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
 	   * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
 	   * i.e. S9[3]: ON (83MHz), OFF (100MHz)
+	   *
+	   * For TX4937:
+	   * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1)
+	   * PCIDIVMODE[10] is 0.
+	   * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8)
+	   * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4)
+	   * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9)
+	   * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5)
+	   * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10)
+	   * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5)
+	   *
 	 */
 	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
-				       "ccfg is %lx, DIV is %x\n",
-				       (unsigned long) tx4927_ccfgptr->
-				       ccfg, TX4927_CCFG_PCIDIVMODE_MASK);
+				       "ccfg is %lx, PCIDIVMODE is %x\n",
+				       (unsigned long) tx4927_ccfgptr->ccfg,
+				       (unsigned long) tx4927_ccfgptr->ccfg &
+				       (mips_machtype == MACH_TOSHIBA_RBTX4937 ?
+					TX4937_CCFG_PCIDIVMODE_MASK :
+					TX4927_CCFG_PCIDIVMODE_MASK));
 
 	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
 				       "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n",
@@ -842,20 +882,30 @@
 				       (unsigned long) tx4927_ccfgptr->
 				       ccfg & TX4927_CCFG_PCIXARB);
 
-	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
-				       "PCIDIVMODE is %lx\n",
-				       (unsigned long) tx4927_ccfgptr->
-				       ccfg & TX4927_CCFG_PCIDIVMODE_MASK);
-
-	switch ((unsigned long) tx4927_ccfgptr->
-		ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
-	case TX4927_CCFG_PCIDIVMODE_2_5:
-	case TX4927_CCFG_PCIDIVMODE_5:
-		tx4927_cpu_clock = 166000000;	/* 166MHz */
-		break;
-	default:
-		tx4927_cpu_clock = 200000000;	/* 200MHz */
-	}
+	if (mips_machtype == MACH_TOSHIBA_RBTX4937)
+		switch ((unsigned long)tx4927_ccfgptr->
+			ccfg & TX4937_CCFG_PCIDIVMODE_MASK) {
+		case TX4937_CCFG_PCIDIVMODE_8:
+		case TX4937_CCFG_PCIDIVMODE_4:
+			tx4927_cpu_clock = 266666666;	/* 266MHz */
+			break;
+		case TX4937_CCFG_PCIDIVMODE_9:
+		case TX4937_CCFG_PCIDIVMODE_4_5:
+			tx4927_cpu_clock = 300000000;	/* 300MHz */
+			break;
+		default:
+			tx4927_cpu_clock = 333333333;	/* 333MHz */
+		}
+	else
+		switch ((unsigned long)tx4927_ccfgptr->
+			ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
+		case TX4927_CCFG_PCIDIVMODE_2_5:
+		case TX4927_CCFG_PCIDIVMODE_5:
+			tx4927_cpu_clock = 166666666;	/* 166MHz */
+			break;
+		default:
+			tx4927_cpu_clock = 200000000;	/* 200MHz */
+		}
 
 	/* CCFG */
 	/* enable Timeout BusError */
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 9f1dcc8..5c7ace9 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -20,6 +20,8 @@
 #include <linux/interrupt.h>
 #include <linux/console.h>
 #include <linux/pci.h>
+#include <linux/pm.h>
+
 #include <asm/wbflush.h>
 #include <asm/reboot.h>
 #include <asm/irq.h>
@@ -1003,7 +1005,7 @@
 
 	_machine_restart = rbtx4938_machine_restart;
 	_machine_halt = rbtx4938_machine_halt;
-	_machine_power_off = rbtx4938_machine_power_off;
+	pm_power_off = rbtx4938_machine_power_off;
 
 	*rbtx4938_led_ptr = 0xff;
 	printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr);
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c
index 02bf4f7..5e46979 100644
--- a/arch/mips/vr41xx/common/pmu.c
+++ b/arch/mips/vr41xx/common/pmu.c
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
+#include <linux/pm.h>
 #include <linux/smp.h>
 #include <linux/types.h>
 
@@ -114,7 +115,7 @@
 
 	_machine_restart = vr41xx_restart;
 	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
+	pm_power_off = vr41xx_power_off;
 
 	return 0;
 }
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index 29b4d61..05273cc 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -468,19 +468,23 @@
 	if ( opcode == 1 ) { /* GETFSIND */	
 		len = strlen_user((char *)arg1);
 		printk(KERN_DEBUG "len of arg1 = %d\n", len);
-
-		fsname = (char *) kmalloc(len+1, GFP_KERNEL);
+		if (len == 0)
+			return 0;
+		fsname = (char *) kmalloc(len, GFP_KERNEL);
 		if ( !fsname ) {
 			printk(KERN_DEBUG "failed to kmalloc fsname\n");
 			return 0;
 		}
 
-		if ( copy_from_user(fsname, (char *)arg1, len+1) ) {
+		if ( copy_from_user(fsname, (char *)arg1, len) ) {
 			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
 			kfree(fsname);
 			return 0;
 		}
 
+		/* String could be altered by userspace after strlen_user() */
+		fsname[len] = '\0';
+
 		printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
 		if ( !strcmp(fsname, "hfs") ) {
 			fstype = 0;
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index e4362df..340730f 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -66,7 +66,7 @@
 #else
 	ld	r4,PACACURRENT(r13)
 	addi	r5,r4,THREAD		/* Get THREAD */
-	ld	r4,THREAD_FPEXC_MODE(r5)
+	lwz	r4,THREAD_FPEXC_MODE(r5)
 	ori	r12,r12,MSR_FP
 	or	r12,r12,r4
 	std	r12,_MSR(r1)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 3082684..4156596 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -749,11 +749,12 @@
 
 	.globl decrementer_iSeries_masked
 decrementer_iSeries_masked:
+	/* We may not have a valid TOC pointer in here. */
 	li	r11,1
 	ld	r12,PACALPPACAPTR(r13)
 	stb	r11,LPPACADECRINT(r12)
-	LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy)
-	lwz	r12,ADDROFF(tb_ticks_per_jiffy)(r12)
+	LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy)
+	lwz	r12,0(r12)
 	mtspr	SPRN_DEC,r12
 	/* fall through */
 
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 4d9b438..946f321 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -334,9 +334,6 @@
 
 	spin_unlock_irqrestore(&(tbl->it_lock), flags);
 
-	/* Make sure updates are seen by hardware */
-	mb();
-
 	DBG("mapped %d elements:\n", outcount);
 
 	/* For the sake of iommu_unmap_sg, we clear out the length in the
@@ -347,6 +344,10 @@
 		outs->dma_address = DMA_ERROR_CODE;
 		outs->dma_length = 0;
 	}
+
+	/* Make sure updates are seen by hardware */
+	mb();
+
 	return outcount;
 
  failure:
@@ -358,6 +359,8 @@
 			npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr)
 				>> PAGE_SHIFT;
 			__iommu_free(tbl, vaddr, npages);
+			s->dma_address = DMA_ERROR_CODE;
+			s->dma_length = 0;
 		}
 	}
 	spin_unlock_irqrestore(&(tbl->it_lock), flags);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index d50c8df..294832a 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -491,7 +491,12 @@
 	size = 16;
 	finish_node(allnodes, &size, 1);
 	size -= 16;
-	end = start = (unsigned long) __va(lmb_alloc(size, 128));
+
+	if (0 == size)
+		end = start = 0;
+	else
+		end = start = (unsigned long)__va(lmb_alloc(size, 128));
+
 	finish_node(allnodes, &end, 0);
 	BUG_ON(end != start + size);
 
@@ -1398,8 +1403,8 @@
 
 	read_lock(&devtree_lock);
 	np = from ? from->allnext : allnodes;
-	for (; np != 0; np = np->allnext)
-		if (np->name != 0 && strcasecmp(np->name, name) == 0
+	for (; np != NULL; np = np->allnext)
+		if (np->name != NULL && strcasecmp(np->name, name) == 0
 		    && of_node_get(np))
 			break;
 	if (from)
@@ -1917,3 +1922,30 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_KEXEC
+/* We may have allocated the flat device tree inside the crash kernel region
+ * in prom_init. If so we need to move it out into regular memory. */
+void kdump_move_device_tree(void)
+{
+	unsigned long start, end;
+	struct boot_param_header *new;
+
+	start = __pa((unsigned long)initial_boot_params);
+	end = start + initial_boot_params->totalsize;
+
+	if (end < crashk_res.start || start > crashk_res.end)
+		return;
+
+	new = (struct boot_param_header*)
+		__va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE));
+
+	memcpy(new, initial_boot_params, initial_boot_params->totalsize);
+
+	initial_boot_params = new;
+
+	DBG("Flat device tree blob moved to %p\n", initial_boot_params);
+
+	/* XXX should we unreserve the old DT? */
+}
+#endif /* CONFIG_KEXEC */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7881ec9..ec7153f 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2098,6 +2098,10 @@
 	 */
 	prom_init_stdout();
 
+	/* Bail if this is a kdump kernel. */
+	if (PHYSICAL_START > 0)
+		prom_panic("Error: You can't boot a kdump kernel from OF!\n");
+
 	/*
 	 * Check for an initrd
 	 */
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index a8099c8..3934c22 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -465,8 +465,10 @@
 	if (parent == NULL)
 		return NULL;
 	bus = of_match_bus(parent);
-	if (strcmp(bus->name, "pci"))
+	if (strcmp(bus->name, "pci")) {
+		of_node_put(parent);
 		return NULL;
+	}
 	bus->count_cells(dev, &na, &ns);
 	of_node_put(parent);
 	if (!OF_CHECK_COUNTS(na, ns))
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 7fe4a5c..b5b2add 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -22,6 +22,7 @@
 
 #include <asm/prom.h>
 #include <asm/rtas.h>
+#include <asm/hvcall.h>
 #include <asm/semaphore.h>
 #include <asm/machdep.h>
 #include <asm/page.h>
@@ -565,6 +566,7 @@
 #ifdef CONFIG_PPC_PSERIES
 static void rtas_percpu_suspend_me(void *info)
 {
+	int i;
 	long rc;
 	long flags;
 	struct rtas_suspend_me_data *data =
@@ -587,18 +589,16 @@
 
 	if (rc == H_Continue) {
 		data->waiting = 0;
-		rtas_call(ibm_suspend_me_token, 0, 1,
-			  data->args->args);
+		data->args->args[data->args->nargs] =
+			rtas_call(ibm_suspend_me_token, 0, 1, NULL);
+		for_each_cpu(i)
+			plpar_hcall_norets(H_PROD,i);
 	} else {
 		data->waiting = -EBUSY;
 		printk(KERN_ERR "Error on H_Join hypervisor call\n");
 	}
 
 out:
-	/* before we restore interrupts, make sure we don't
-	 * generate a spurious soft lockup errors
-	 */
-	touch_softlockup_watchdog();
 	local_irq_restore(flags);
 	return;
 }
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 5050009..aaf384c 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -672,8 +672,7 @@
 static void remove_flash_pde(struct proc_dir_entry *dp)
 {
 	if (dp) {
-		if (dp->data != NULL)
-			kfree(dp->data);
+		kfree(dp->data);
 		dp->owner = NULL;
 		remove_proc_entry(dp->name, dp->parent);
 	}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e29b275..a717dff 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -398,6 +398,9 @@
 {
 	DBG(" -> setup_system()\n");
 
+#ifdef CONFIG_KEXEC
+	kdump_move_device_tree();
+#endif
 	/*
 	 * Unflatten the device-tree passed by prom_init or kexec
 	 */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index c6d0595..bd837b5d 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -142,11 +142,7 @@
 	return 0;
 }
 
-static inline compat_uptr_t to_user_ptr(void *kp)
-{
-	return (compat_uptr_t)(u64)kp;
-}
-
+#define to_user_ptr(p)		ptr_to_compat(p)
 #define from_user_ptr(p)	compat_ptr(p)
 
 static inline int save_general_regs(struct pt_regs *regs,
@@ -213,8 +209,8 @@
 	return 0;
 }
 
-#define to_user_ptr(p)		(p)
-#define from_user_ptr(p)	(p)
+#define to_user_ptr(p)		((unsigned long)(p))
+#define from_user_ptr(p)	((void __user *)(p))
 
 static inline int save_general_regs(struct pt_regs *regs,
 		struct mcontext __user *frame)
@@ -526,7 +522,7 @@
 
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 	if (!ret && oact) {
-		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
+		ret = put_user(to_user_ptr(old_ka.sa.sa_handler), &oact->sa_handler);
 		ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 	}
@@ -675,8 +671,8 @@
 int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
 		      int r6, int r7, int r8, struct pt_regs *regs)
 {
-	stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
-	stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old;
+	stack_32_t __user * newstack = compat_ptr(__new);
+	stack_32_t __user * oldstack = compat_ptr(__old);
 	stack_t uss, uoss;
 	int ret;
 	mm_segment_t old_fs;
@@ -708,7 +704,7 @@
 	set_fs(old_fs);
 	/* Copy the stack information to the user output buffer */
 	if (!ret && oldstack  &&
-		(put_user((long)uoss.ss_sp, &oldstack->ss_sp) ||
+		(put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) ||
 		 __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
 		 __put_user(uoss.ss_size, &oldstack->ss_size)))
 		return -EFAULT;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index b319311..497a5d3 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -60,8 +60,8 @@
 	struct ucontext uc;
 	unsigned long _unused[2];
 	unsigned int tramp[TRAMP_SIZE];
-	struct siginfo *pinfo;
-	void *puc;
+	struct siginfo __user *pinfo;
+	void __user *puc;
 	struct siginfo info;
 	/* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
 	char abigap[288];
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index c8458c5..13595a6 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -540,6 +540,9 @@
 	if (smp_ops->take_timebase)
 		smp_ops->take_timebase();
 
+	if (system_state > SYSTEM_BOOTING)
+		per_cpu(last_jiffy, cpu) = get_tb();
+
 	spin_lock(&call_lock);
 	cpu_set(cpu, cpu_online_map);
 	spin_unlock(&call_lock);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c4a294d..1886045 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -612,10 +612,10 @@
 
 	ppc_tb_freq = DEFAULT_TB_FREQ;		/* hardcoded default */
 	node_found = 0;
-	if (cpu != 0) {
+	if (cpu) {
 		fp = (unsigned int *)get_property(cpu, "timebase-frequency",
 						  NULL);
-		if (fp != 0) {
+		if (fp) {
 			node_found = 1;
 			ppc_tb_freq = *fp;
 		}
@@ -626,10 +626,10 @@
 
 	ppc_proc_freq = DEFAULT_PROC_FREQ;
 	node_found = 0;
-	if (cpu != 0) {
+	if (cpu) {
 		fp = (unsigned int *)get_property(cpu, "clock-frequency",
 						  NULL);
-		if (fp != 0) {
+		if (fp) {
 			node_found = 1;
 			ppc_proc_freq = *fp;
 		}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 2da65a9..5d29dcc 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -144,7 +144,7 @@
 }
 
 #ifdef CONFIG_PPC_MAPLE
-void udbg_maple_real_putc(unsigned char c)
+void udbg_maple_real_putc(char c)
 {
 	if (udbg_comport) {
 		while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
index 9584608..bbe3eac 100644
--- a/arch/powerpc/mm/lmb.c
+++ b/arch/powerpc/mm/lmb.c
@@ -197,6 +197,8 @@
 {
 	struct lmb_region *_rgn = &(lmb.reserved);
 
+	BUG_ON(0 == size);
+
 	return lmb_add_region(_rgn, base, size);
 }
 
@@ -227,6 +229,8 @@
 	long i, j;
 	unsigned long base = 0;
 
+	BUG_ON(0 == size);
+
 #ifdef CONFIG_PPC32
 	/* On 32-bit, make sure we allocate lowmem */
 	if (max_addr == LMB_ALLOC_ANYWHERE)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 15aac0d..550517c 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -435,17 +435,12 @@
 {
 	clear_page(page);
 
-	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
-		return;
 	/*
 	 * We shouldnt have to do this, but some versions of glibc
 	 * require it (ld.so assumes zero filled pages are icache clean)
 	 * - Anton
 	 */
-
-	/* avoid an atomic op if possible */
-	if (test_bit(PG_arch_1, &pg->flags))
-		clear_bit(PG_arch_1, &pg->flags);
+	flush_dcache_page(pg);
 }
 EXPORT_SYMBOL(clear_user_page);
 
@@ -469,12 +464,7 @@
 		return;
 #endif
 
-	if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
-		return;
-
-	/* avoid an atomic op if possible */
-	if (test_bit(PG_arch_1, &pg->flags))
-		clear_bit(PG_arch_1, &pg->flags);
+	flush_dcache_page(pg);
 }
 
 void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 16031b5..3b998a3 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -2,7 +2,7 @@
 obj-y			+= pervasive.o
 
 obj-$(CONFIG_SMP)	+= smp.o
-obj-$(CONFIG_SPU_FS)	+= spufs/ spu-base.o
+obj-$(CONFIG_SPU_FS)	+= spu-base.o spufs/
 
 spu-base-y		+= spu_base.o spu_priv1.o
 
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
index 3a2057f..814f547 100644
--- a/arch/powerpc/platforms/chrp/chrp.h
+++ b/arch/powerpc/platforms/chrp/chrp.h
@@ -5,7 +5,6 @@
 extern void chrp_nvram_init(void);
 extern void chrp_get_rtc_time(struct rtc_time *);
 extern int chrp_set_rtc_time(struct rtc_time *);
-extern void chrp_calibrate_decr(void);
 extern long chrp_time_init(void);
 
 extern void chrp_find_bridges(void);
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 00c52f2..8ef279a 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -204,9 +204,11 @@
 	struct device_node *root = find_path_device("/");
 	struct device_node *rtas;
 
+	of_node_get(root);
 	rtas = of_find_node_by_name (root, "rtas");
 	if (rtas) {
 		hose->ops = &rtas_pci_ops;
+		of_node_put(rtas);
 	} else {
 		printk ("RTAS supporting Pegasos OF not found, please upgrade"
 			" your firmware\n");
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 2dc87aa..e1fadbf 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -506,7 +506,7 @@
 	ppc_md.halt           = rtas_halt;
 
 	ppc_md.time_init      = chrp_time_init;
-	ppc_md.calibrate_decr = chrp_calibrate_decr;
+	ppc_md.calibrate_decr = generic_calibrate_decr;
 
 	/* this may get overridden with rtas routines later... */
 	ppc_md.set_rtc_time   = chrp_set_rtc_time;
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index 36a0f97..78df2e7 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -167,24 +167,3 @@
 	tm->tm_mon = mon;
 	tm->tm_year = year;
 }
-
-
-void __init chrp_calibrate_decr(void)
-{
-	struct device_node *cpu;
-	unsigned int freq, *fp;
-
-	/*
-	 * The cpu node should have a timebase-frequency property
-	 * to tell us the rate at which the decrementer counts.
-	 */
-	freq = 16666000;		/* hardcoded default */
-	cpu = find_type_devices("cpu");
-	if (cpu != 0) {
-		fp = (unsigned int *)
-			get_property(cpu, "timebase-frequency", NULL);
-		if (fp != 0)
-			freq = *fp;
-	}
-	ppc_tb_freq = freq;
-}
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 535c802..87eb6bb 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -1052,8 +1052,7 @@
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus);
 
-extern int pmac_i2c_match_adapter(struct device_node *dev,
-				  struct i2c_adapter *adapter)
+int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter)
 {
 	struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev);
 
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index f671ed2..de3f30e 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -136,14 +136,14 @@
 	|(((unsigned int)(off)) & 0xFCUL) \
 	|1UL)
 
-static unsigned long macrisc_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose,
 					       u8 bus, u8 dev_fn, u8 offset)
 {
 	unsigned int caddr;
 
 	if (bus == hose->first_busno) {
 		if (dev_fn < (11 << 3))
-			return 0;
+			return NULL;
 		caddr = MACRISC_CFA0(dev_fn, offset);
 	} else
 		caddr = MACRISC_CFA1(bus, dev_fn, offset);
@@ -154,14 +154,14 @@
 	} while (in_le32(hose->cfg_addr) != caddr);
 
 	offset &= has_uninorth ? 0x07 : 0x03;
-	return ((unsigned long)hose->cfg_data) + offset;
+	return hose->cfg_data + offset;
 }
 
 static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
 				      int offset, int len, u32 *val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -177,13 +177,13 @@
 	 */
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)addr);
+		*val = in_8(addr);
 		break;
 	case 2:
-		*val = in_le16((u16 *)addr);
+		*val = in_le16(addr);
 		break;
 	default:
-		*val = in_le32((u32 *)addr);
+		*val = in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -193,7 +193,7 @@
 				       int offset, int len, u32 val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -209,16 +209,16 @@
 	 */
 	switch (len) {
 	case 1:
-		out_8((u8 *)addr, val);
-		(void) in_8((u8 *)addr);
+		out_8(addr, val);
+		(void) in_8(addr);
 		break;
 	case 2:
-		out_le16((u16 *)addr, val);
-		(void) in_le16((u16 *)addr);
+		out_le16(addr, val);
+		(void) in_le16(addr);
 		break;
 	default:
-		out_le32((u32 *)addr, val);
-		(void) in_le32((u32 *)addr);
+		out_le32(addr, val);
+		(void) in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -348,25 +348,23 @@
 		+ (((unsigned int)bus) << 16) \
 		+ 0x01000000UL)
 
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
 					     u8 bus, u8 devfn, u8 offset)
 {
 	if (bus == hose->first_busno) {
 		/* For now, we don't self probe U3 HT bridge */
 		if (PCI_SLOT(devfn) == 0)
-			return 0;
-		return ((unsigned long)hose->cfg_data) +
-			U3_HT_CFA0(devfn, offset);
+			return NULL;
+		return hose->cfg_data + U3_HT_CFA0(devfn, offset);
 	} else
-		return ((unsigned long)hose->cfg_data) +
-			U3_HT_CFA1(bus, devfn, offset);
+		return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
 }
 
 static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
 				    int offset, int len, u32 *val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -400,13 +398,13 @@
 	 */
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)addr);
+		*val = in_8(addr);
 		break;
 	case 2:
-		*val = in_le16((u16 *)addr);
+		*val = in_le16(addr);
 		break;
 	default:
-		*val = in_le32((u32 *)addr);
+		*val = in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -416,7 +414,7 @@
 				     int offset, int len, u32 val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -442,16 +440,16 @@
 	 */
 	switch (len) {
 	case 1:
-		out_8((u8 *)addr, val);
-		(void) in_8((u8 *)addr);
+		out_8(addr, val);
+		(void) in_8(addr);
 		break;
 	case 2:
-		out_le16((u16 *)addr, val);
-		(void) in_le16((u16 *)addr);
+		out_le16(addr, val);
+		(void) in_le16(addr);
 		break;
 	default:
-		out_le32((u32 *)addr, val);
-		(void) in_le32((u32 *)addr);
+		out_le32((u32 __iomem *)addr, val);
+		(void) in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -476,7 +474,7 @@
 	 |(((unsigned int)(off)) & 0xfcU)	\
 	 |1UL)
 
-static unsigned long u4_pcie_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose,
 					u8 bus, u8 dev_fn, int offset)
 {
 	unsigned int caddr;
@@ -492,14 +490,14 @@
 	} while (in_le32(hose->cfg_addr) != caddr);
 
 	offset &= 0x03;
-	return ((unsigned long)hose->cfg_data) + offset;
+	return hose->cfg_data + offset;
 }
 
 static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
 			       int offset, int len, u32 *val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -515,13 +513,13 @@
 	 */
 	switch (len) {
 	case 1:
-		*val = in_8((u8 *)addr);
+		*val = in_8(addr);
 		break;
 	case 2:
-		*val = in_le16((u16 *)addr);
+		*val = in_le16(addr);
 		break;
 	default:
-		*val = in_le32((u32 *)addr);
+		*val = in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -531,7 +529,7 @@
 				int offset, int len, u32 val)
 {
 	struct pci_controller *hose;
-	unsigned long addr;
+	volatile void __iomem *addr;
 
 	hose = pci_bus_to_host(bus);
 	if (hose == NULL)
@@ -547,16 +545,16 @@
 	 */
 	switch (len) {
 	case 1:
-		out_8((u8 *)addr, val);
-		(void) in_8((u8 *)addr);
+		out_8(addr, val);
+		(void) in_8(addr);
 		break;
 	case 2:
-		out_le16((u16 *)addr, val);
-		(void) in_le16((u16 *)addr);
+		out_le16(addr, val);
+		(void) in_le16(addr);
 		break;
 	default:
-		out_le32((u32 *)addr, val);
-		(void) in_le32((u32 *)addr);
+		out_le32(addr, val);
+		(void) in_le32(addr);
 		break;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -773,8 +771,7 @@
 	 * the reg address cell, we shall fix that by killing struct
 	 * reg_property and using some accessor functions instead
 	 */
-	hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000,
-							   0x02000000);
+	hose->cfg_data = ioremap(0xf2000000, 0x02000000);
 
 	/*
 	 * /ht node doesn't expose a "ranges" property, so we "remove"
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 89c4c36..1955462 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -82,8 +82,6 @@
 
 #undef SHOW_GATWICK_IRQS
 
-unsigned char drive_info;
-
 int ppc_override_l2cr = 0;
 int ppc_override_l2cr_value;
 int has_l2cache = 0;
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 6373372..e3cbba4 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -333,7 +333,7 @@
 		rc = eeh_reset_device(frozen_pdn, NULL);
 		if (rc)
 			goto hard_fail;
-		pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+		pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
 	}
 
 	/* If all devices reported they can proceed, the re-enable PIO */
@@ -342,11 +342,11 @@
 		rc = eeh_reset_device(frozen_pdn, NULL);
 		if (rc)
 			goto hard_fail;
-		pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+		pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
 	}
 
 	/* Tell all device drivers that they can resume operations */
-	pci_walk_bus(frozen_bus, eeh_report_resume, 0);
+	pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
 
 	return;
 	
@@ -367,7 +367,7 @@
 	eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
 
 	/* Notify all devices that they're about to go down. */
-	pci_walk_bus(frozen_bus, eeh_report_failure, 0);
+	pci_walk_bus(frozen_bus, eeh_report_failure, NULL);
 
 	/* Shut down the device drivers for good. */
 	pcibios_remove_pci_devices(frozen_bus);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index da6ceba..9edeca8 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -585,7 +585,7 @@
 static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
 {
 	/* Don't risk a hypervisor call if we're crashing */
-	if (!crash_shutdown) {
+	if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
 		unsigned long vpa = __pa(get_lppaca());
 
 		if (unregister_vpa(hard_smp_processor_id(), vpa)) {
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 977de9d..6298264 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -59,7 +59,7 @@
 static u32 *dart_vbase;
 
 /* Mapped base address for the dart */
-static unsigned int *__iomem dart;
+static unsigned int __iomem *dart;
 
 /* Dummy val that entries are set to when unused */
 static unsigned int dart_emptyval;
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index 3e6ca7f..c1e89ad 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -810,13 +810,16 @@
 	mtspr	SPRN_MD_TWC, r9
 	li	r11, MI_BOOTINIT	/* Create RPN for address 0 */
 	addis	r11, r11, 0x0080	/* Add 8M */
-	mtspr	SPRN_MD_RPN, r8
+	mtspr	SPRN_MD_RPN, r11
+
+	addi	r10, r10, 0x0100
+	mtspr	SPRN_MD_CTR, r10
 
 	addis	r8, r8, 0x0080		/* Add 8M */
 	mtspr	SPRN_MD_EPN, r8
 	mtspr	SPRN_MD_TWC, r9
 	addis	r11, r11, 0x0080	/* Add 8M */
-	mtspr	SPRN_MD_RPN, r8
+	mtspr	SPRN_MD_RPN, r11
 #endif
 
 	/* Since the cache is enabled according to the information we
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 3a6e4bc..15bd9b4 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -186,11 +186,15 @@
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(_tlbie);
 #ifdef CONFIG_ALTIVEC
+#ifndef CONFIG_SMP
 EXPORT_SYMBOL(last_task_used_altivec);
+#endif
 EXPORT_SYMBOL(giveup_altivec);
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_SPE
+#ifndef CONFIG_SMP
 EXPORT_SYMBOL(last_task_used_spe);
+#endif
 EXPORT_SYMBOL(giveup_spe);
 #endif /* CONFIG_SPE */
 #ifdef CONFIG_SMP
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
index ab34b1d..2fe28de 100644
--- a/arch/ppc/syslib/ocp.c
+++ b/arch/ppc/syslib/ocp.c
@@ -189,8 +189,8 @@
 struct bus_type ocp_bus_type = {
 	.name = "ocp",
 	.match = ocp_device_match,
-	.probe = ocp_driver_probe,
-	.remove = ocp_driver_remove,
+	.probe = ocp_device_probe,
+	.remove = ocp_device_remove,
 	.suspend = ocp_device_suspend,
 	.resume = ocp_device_resume,
 };
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index bf9a7a3..cc20f0e 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -100,12 +100,12 @@
 #define SET_STAT_UID(stat, uid)		(stat).st_uid = high2lowuid(uid)
 #define SET_STAT_GID(stat, gid)		(stat).st_gid = high2lowgid(gid)
 
-asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
 {
 	return sys_chown(filename, low2highuid(user), low2highgid(group));
 }
 
-asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group)
 {
 	return sys_lchown(filename, low2highuid(user), low2highgid(group));
 }
@@ -141,7 +141,7 @@
 		low2highuid(suid));
 }
 
-asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
+asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid)
 {
 	int retval;
 
@@ -158,7 +158,7 @@
 		low2highgid(sgid));
 }
 
-asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
+asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
 {
 	int retval;
 
@@ -179,7 +179,7 @@
 	return sys_setfsgid((gid_t)gid);
 }
 
-static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
+static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
 {
 	int i;
 	u16 group;
@@ -193,7 +193,7 @@
 	return 0;
 }
 
-static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
+static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)
 {
 	int i;
 	u16 group;
@@ -207,7 +207,7 @@
 	return 0;
 }
 
-asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
 {
 	int i;
 
@@ -231,7 +231,7 @@
 	return i;
 }
 
-asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
 {
 	struct group_info *group_info;
 	int retval;
@@ -278,14 +278,14 @@
 
 /* 32-bit timeval and related flotsam.  */
 
-static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
+static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
 {
 	return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
 		(__get_user(o->tv_sec, &i->tv_sec) ||
 		 __get_user(o->tv_usec, &i->tv_usec)));
 }
 
-static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
+static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
 {
 	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
 		(__put_user(i->tv_sec, &o->tv_sec) ||
@@ -341,7 +341,7 @@
 	return -ENOSYS;
 }
 
-asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low)
+asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
 {
 	if ((int)high < 0)
 		return -EINVAL;
@@ -357,7 +357,7 @@
 		return sys_ftruncate(fd, (high << 32) | low);
 }
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
 	int err;
 
@@ -591,7 +591,7 @@
 
 extern struct timezone sys_tz;
 
-asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
 	if (tv) {
 		struct timeval ktv;
@@ -606,7 +606,7 @@
 	return 0;
 }
 
-static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
 {
 	long usec;
 
@@ -620,7 +620,7 @@
 	return 0;
 }
 
-asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
 	struct timespec kts;
 	struct timezone ktz;
@@ -645,7 +645,7 @@
 	return -ERESTARTNOHAND;
 }
 
-asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
+asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
 				size_t count, u32 poshi, u32 poslo)
 {
 	if ((compat_ssize_t) count < 0)
@@ -653,7 +653,7 @@
 	return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf,
+asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
 				size_t count, u32 poshi, u32 poslo)
 {
 	if ((compat_ssize_t) count < 0)
@@ -666,7 +666,7 @@
 	return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
 }
 
-asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count)
+asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count)
 {
 	mm_segment_t old_fs = get_fs();
 	int ret;
@@ -686,7 +686,7 @@
 }
 
 asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
-				compat_loff_t *offset, s32 count)
+				compat_loff_t __user *offset, s32 count)
 {
 	mm_segment_t old_fs = get_fs();
 	int ret;
@@ -722,7 +722,7 @@
 
 extern int do_adjtimex(struct timex *);
 
-asmlinkage long sys32_adjtimex(struct timex32 *utp)
+asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
 {
 	struct timex txc;
 	int ret;
@@ -789,12 +789,13 @@
 	u32 __unused[4];
 };
 
-asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
+asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
 {
 	struct __sysctl_args32 tmp;
 	int error;
-	size_t oldlen, *oldlenp = NULL;
-	unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
+	size_t oldlen;
+	size_t __user *oldlenp = NULL;
+	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
 
 	if (copy_from_user(&tmp, args, sizeof(tmp)))
 		return -EFAULT;
@@ -806,20 +807,20 @@
 		   basically copy the whole sysctl.c here, and
 		   glibc's __sysctl uses rw memory for the structure
 		   anyway.  */
-		if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
-		    put_user(oldlen, (size_t *)addr))
+		if (get_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)) ||
+		    put_user(oldlen, (size_t __user *)addr))
 			return -EFAULT;
-		oldlenp = (size_t *)addr;
+		oldlenp = (size_t __user *)addr;
 	}
 
 	lock_kernel();
-	error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
-			  oldlenp, (void *)A(tmp.newval), tmp.newlen);
+	error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, compat_ptr(tmp.oldval),
+			  oldlenp, compat_ptr(tmp.newval), tmp.newlen);
 	unlock_kernel();
 	if (oldlenp) {
 		if (!error) {
-			if (get_user(oldlen, (size_t *)addr) ||
-			    put_user(oldlen, (u32 *)A(tmp.oldlenp)))
+			if (get_user(oldlen, (size_t __user *)addr) ||
+			    put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
 				error = -EFAULT;
 		}
 		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
@@ -853,7 +854,7 @@
 	unsigned long   st_ino;
 };	
 
-static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
+static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)
 {
 	struct stat64_emu31 tmp;
 
@@ -877,7 +878,7 @@
 	return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
 }
 
-asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_stat64(char __user * filename, struct stat64_emu31 __user * statbuf)
 {
 	struct kstat stat;
 	int ret = vfs_stat(filename, &stat);
@@ -886,7 +887,7 @@
 	return ret;
 }
 
-asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_lstat64(char __user * filename, struct stat64_emu31 __user * statbuf)
 {
 	struct kstat stat;
 	int ret = vfs_lstat(filename, &stat);
@@ -895,7 +896,7 @@
 	return ret;
 }
 
-asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf)
 {
 	struct kstat stat;
 	int ret = vfs_fstat(fd, &stat);
@@ -952,7 +953,7 @@
 
 
 asmlinkage unsigned long
-old32_mmap(struct mmap_arg_struct_emu31 *arg)
+old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
 {
 	struct mmap_arg_struct_emu31 a;
 	int error = -EFAULT;
@@ -970,7 +971,7 @@
 }
 
 asmlinkage long 
-sys32_mmap2(struct mmap_arg_struct_emu31 *arg)
+sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
 {
 	struct mmap_arg_struct_emu31 a;
 	int error = -EFAULT;
@@ -982,7 +983,7 @@
 	return error;
 }
 
-asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count)
 {
 	if ((compat_ssize_t) count < 0)
 		return -EINVAL; 
@@ -990,7 +991,7 @@
 	return sys_read(fd, buf, count);
 }
 
-asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
 {
 	if ((compat_ssize_t) count < 0)
 		return -EINVAL; 
@@ -1002,12 +1003,12 @@
 {
         unsigned long clone_flags;
         unsigned long newsp;
-	int *parent_tidptr, *child_tidptr;
+	int __user *parent_tidptr, *child_tidptr;
 
         clone_flags = regs.gprs[3] & 0xffffffffUL;
         newsp = regs.orig_gpr2 & 0x7fffffffUL;
-	parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL);
-	child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL);
+	parent_tidptr = compat_ptr(regs.gprs[4]);
+	child_tidptr = compat_ptr(regs.gprs[5]);
         if (!newsp)
                 newsp = regs.gprs[15];
         return do_fork(clone_flags, newsp, &regs, 0,
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 6a63553..e351780 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -122,8 +122,8 @@
 #ifndef CONFIG_64BIT
 struct sel_arg_struct {
 	unsigned long n;
-	fd_set *inp, *outp, *exp;
-	struct timeval *tvp;
+	fd_set __user *inp, *outp, *exp;
+	struct timeval __user *tvp;
 };
 
 asmlinkage long old_select(struct sel_arg_struct __user *arg)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 5d21e9e..a46793b 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -486,7 +486,7 @@
 		info.si_signo = signal;
 		info.si_errno = 0;
 		info.si_code = ILL_ILLOPC;
-		info.si_addr = (void *) location;
+		info.si_addr = (void __user *) location;
 		do_trap(interruption_code, signal,
 			"illegal operation", regs, &info);
 	}
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index 2d5cb13..b075ab4 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -42,8 +42,8 @@
 static long cmm_timeout_pages = 0;
 static long cmm_timeout_seconds = 0;
 
-static struct cmm_page_array *cmm_page_list = 0;
-static struct cmm_page_array *cmm_timed_page_list = 0;
+static struct cmm_page_array *cmm_page_list = NULL;
+static struct cmm_page_array *cmm_timed_page_list = NULL;
 
 static unsigned long cmm_thread_active = 0;
 static struct work_struct cmm_thread_starter;
@@ -259,7 +259,7 @@
 
 static int
 cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
-		  void *buffer, size_t *lenp, loff_t *ppos)
+		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	char buf[16], *p;
 	long pages;
@@ -300,7 +300,7 @@
 
 static int
 cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
-		    void *buffer, size_t *lenp, loff_t *ppos)
+		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	char buf[64], *p;
 	long pages, seconds;
@@ -419,7 +419,7 @@
 #ifdef CONFIG_CMM_IUCV
 	smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
 #endif
-	INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, 0);
+	INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, NULL);
 	init_waitqueue_head(&cmm_thread_wait);
 	init_timer(&cmm_timer);
 	return 0;
diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c
index c46f915..123abbb 100644
--- a/arch/sh/boards/renesas/rts7751r2d/io.c
+++ b/arch/sh/boards/renesas/rts7751r2d/io.c
@@ -216,24 +216,26 @@
 {
 	volatile __u8 *bp;
 	volatile __u16 *p;
+	unsigned char *s = addr;
 
 	if (CHECK_AX88796L_PORT(port)) {
 		p = (volatile unsigned short *)port88796l(port, 0);
-		while (count--) *((unsigned char *) addr)++ = *p & 0xff;
+		while (count--) *s++ = *p & 0xff;
 	} else if (PXSEG(port))
-		while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port;
+		while (count--) *s++ = *(volatile unsigned char *)port;
 	else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
 		bp = (__u8 *)PCI_IOMAP(port);
-		while (count--) *((volatile unsigned char *) addr)++ = *bp;
+		while (count--) *s++ = *bp;
 	} else {
 		p = (volatile unsigned short *)port2adr(port);
-		while (count--) *((unsigned char *) addr)++ = *p & 0xff;
+		while (count--) *s++ = *p & 0xff;
 	}
 }
 
 void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
 {
 	volatile __u16 *p;
+	__u16 *s = addr;
 
 	if (CHECK_AX88796L_PORT(port))
 		p = (volatile unsigned short *)port88796l(port, 1);
@@ -243,7 +245,7 @@
 		p = (volatile unsigned short *)PCI_IOMAP(port);
 	else
 		p = (volatile unsigned short *)port2adr(port);
-	while (count--) *((__u16 *) addr)++ = *p;
+	while (count--) *s++ = *p;
 }
 
 void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
@@ -252,8 +254,9 @@
 		maybebadio(insl, port);
 	else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
 		volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
+		__u32 *s = addr;
 
-		while (count--) *((__u32 *) addr)++ = *p;
+		while (count--) *s++ = *p;
 	} else
 		maybebadio(insl, port);
 }
@@ -262,24 +265,26 @@
 {
 	volatile __u8 *bp;
 	volatile __u16 *p;
+	const __u8 *s = addr;
 
 	if (CHECK_AX88796L_PORT(port)) {
 		p = (volatile unsigned short *)port88796l(port, 0);
-		while (count--) *p = *((unsigned char *) addr)++;
+		while (count--) *p = *s++;
 	} else if (PXSEG(port))
-		while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++;
+		while (count--) *(volatile unsigned char *)port = *s++;
 	else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
 		bp = (__u8 *)PCI_IOMAP(port);
-		while (count--) *bp = *((volatile unsigned char *) addr)++;
+		while (count--) *bp = *s++;
 	} else {
 		p = (volatile unsigned short *)port2adr(port);
-		while (count--) *p = *((unsigned char *) addr)++;
+		while (count--) *p = *s++;
 	}
 }
 
 void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
 {
 	volatile __u16 *p;
+	const __u16 *s = addr;
 
 	if (CHECK_AX88796L_PORT(port))
 		p = (volatile unsigned short *)port88796l(port, 1);
@@ -289,7 +294,7 @@
 		p = (volatile unsigned short *)PCI_IOMAP(port);
 	else
 		p = (volatile unsigned short *)port2adr(port);
-	while (count--) *p = *((__u16 *) addr)++;
+	while (count--) *p = *s++;
 }
 
 void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
@@ -298,8 +303,9 @@
 		maybebadio(outsl, port);
 	else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
 		volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
+		const __u32 *s = addr;
 
-		while (count--) *p = *((__u32 *) addr)++;
+		while (count--) *p = *s++;
 	} else
 		maybebadio(outsl, port);
 }
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c
index 472b450..de29c45 100644
--- a/arch/sh64/kernel/sh_ksyms.c
+++ b/arch/sh64/kernel/sh_ksyms.c
@@ -31,14 +31,6 @@
 
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 
-#if 0
-/* Not yet - there's no declaration of drive_info anywhere. */
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(iounmap);
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 267ec8f..887f6a1 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -38,7 +38,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 299      /* Each OS is different... */
+#define NR_SYSCALLS 300      /* Each OS is different... */
 
 /* These are just handy. */
 #define _SV	save	%sp, -STACKFRAME_SZ, %sp
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index fbb05a4..118cac8 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -54,7 +54,7 @@
  * This is done via auxio, but could be used as a fallback
  * handler when auxio is not present-- unused for now...
  */
-void (*pm_power_off)(void);
+void (*pm_power_off)(void) = machine_power_off;
 
 /*
  * sysctl - toggle power-off restriction for serial console 
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 6877ae4..c031470 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -78,7 +78,7 @@
 /*280*/	.long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
 /*285*/	.long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat
 /*290*/	.long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-/*295*/	.long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
+/*295*/	.long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
 
 #ifdef CONFIG_SUNOS_EMUL
 	/* Now the SunOS syscall table. */
@@ -190,5 +190,6 @@
 /*290*/	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys
 
 #endif
diff --git a/arch/sparc64/boot/.gitignore b/arch/sparc64/boot/.gitignore
new file mode 100644
index 0000000..36356f9
--- /dev/null
+++ b/arch/sparc64/boot/.gitignore
@@ -0,0 +1,4 @@
+image
+tftpboot.img
+vmlinux.aout
+piggyback
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 9ceddad..069d497 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1
-# Wed Jan 18 13:41:02 2006
+# Linux kernel version: 2.6.16-rc2
+# Tue Feb  7 17:47:18 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -23,7 +23,6 @@
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -31,7 +30,7 @@
 # General setup
 #
 CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -155,6 +154,7 @@
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -224,6 +224,11 @@
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 CONFIG_VLAN_8021Q=m
@@ -233,11 +238,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -657,6 +657,7 @@
 CONFIG_SERIAL_SUNSAB=m
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 
@@ -765,6 +766,7 @@
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
@@ -1118,6 +1120,10 @@
 #
 
 #
+# EDAC - error detection and reporting (RAS)
+#
+
+#
 # Misc Linux/SPARC drivers
 #
 CONFIG_SUN_OPENPROMIO=m
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 12911e7..a73553a 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -25,7 +25,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 299      /* Each OS is different... */
+#define NR_SYSCALLS 300      /* Each OS is different... */
 
 	.text
 	.align		32
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 2881faf..5928b3c 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -79,7 +79,7 @@
 /*280*/	.word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
 	.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat
 /*285*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-	.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll
+	.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
 
 #endif /* CONFIG_COMPAT */
 
@@ -148,7 +148,7 @@
 /*280*/	.word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
 	.word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
 /*285*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-	.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
+	.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -261,4 +261,5 @@
 /*290*/	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys
 #endif
diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S
index d25667e..7043ca1 100644
--- a/arch/sparc64/solaris/systbl.S
+++ b/arch/sparc64/solaris/systbl.S
@@ -283,32 +283,3 @@
 	.word solaris_unimplemented	/* 			253	*/
 	.word solaris_unimplemented	/* 			254	*/
 	.word solaris_unimplemented	/* 			255	*/
-	.word solaris_unimplemented	/* 			256	*/
-	.word solaris_unimplemented	/* 			257	*/
-	.word solaris_unimplemented	/* 			258	*/
-	.word solaris_unimplemented	/* 			259	*/
-	.word solaris_unimplemented	/* 			260	*/
-	.word solaris_unimplemented	/* 			261	*/
-	.word solaris_unimplemented	/* 			262	*/
-	.word solaris_unimplemented	/* 			263	*/
-	.word solaris_unimplemented	/* 			264	*/
-	.word solaris_unimplemented	/* 			265	*/
-	.word solaris_unimplemented	/* 			266	*/
-	.word solaris_unimplemented	/* 			267	*/
-	.word solaris_unimplemented	/* 			268	*/
-	.word solaris_unimplemented	/* 			269	*/
-	.word solaris_unimplemented	/* 			270	*/
-	.word solaris_unimplemented	/* 			271	*/
-	.word solaris_unimplemented	/* 			272	*/
-	.word solaris_unimplemented	/* 			273	*/
-	.word solaris_unimplemented	/* 			274	*/
-	.word solaris_unimplemented	/* 			275	*/
-	.word solaris_unimplemented	/* 			276	*/
-	.word solaris_unimplemented	/* 			277	*/
-	.word solaris_unimplemented	/* 			278	*/
-	.word solaris_unimplemented	/* 			279	*/
-	.word solaris_unimplemented	/* 			280	*/
-	.word solaris_unimplemented	/* 			281	*/
-	.word solaris_unimplemented	/* 			282	*/
-	.word solaris_unimplemented	/* 			283	*/
-
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 5d50d4a..2f880cb 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -9,6 +9,7 @@
 #include <termios.h>
 #include <string.h>
 #include <signal.h>
+#include <sched.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -73,7 +74,6 @@
 struct winch_data {
 	int pty_fd;
 	int pipe_fd;
-	int close_me;
 };
 
 static int winch_thread(void *arg)
@@ -84,7 +84,6 @@
 	int count, err;
 	char c = 1;
 
-	os_close_file(data->close_me);
 	pty_fd = data->pty_fd;
 	pipe_fd = data->pipe_fd;
 	count = os_write_file(pipe_fd, &c, sizeof(c));
@@ -153,15 +152,16 @@
 	}
 
 	data = ((struct winch_data) { .pty_fd 		= fd,
-				      .pipe_fd 		= fds[1],
-				      .close_me 	= fds[0] } );
-	err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+				      .pipe_fd 		= fds[1] } );
+	/* CLONE_FILES so this thread doesn't hold open files which are open
+	 * now, but later closed.  This is a problem with /dev/net/tun.
+	 */
+	err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0);
 	if(err < 0){
 		printk("fork of winch_thread failed - errno = %d\n", errno);
 		goto out_close;
 	}
 
-	os_close_file(fds[1]);
 	*fd_out = fds[0];
 	n = os_read_file(fds[0], &c, sizeof(c));
 	if(n != sizeof(c)){
@@ -169,13 +169,12 @@
 		printk("read failed, err = %d\n", -n);
 		printk("fd %d will not support SIGWINCH\n", fd);
                 err = -EINVAL;
-		goto out_close1;
+		goto out_close;
 	}
 	return err ;
 
  out_close:
 	os_close_file(fds[1]);
- out_close1:
 	os_close_file(fds[0]);
  out:
 	return err;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 8ebb224..8c7279b 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -131,9 +131,8 @@
 			     SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
 	if(err != 0){
 		printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
-		if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
-		lp->fd = -1;
 		err = -ENETUNREACH;
+		goto out_close;
 	}
 
 	lp->tl.data = (unsigned long) &lp->user;
@@ -145,9 +144,19 @@
 	 */
 	while((err = uml_net_rx(dev)) > 0) ;
 
- out:
 	spin_unlock(&lp->lock);
-	return(err);
+
+	spin_lock(&opened_lock);
+	list_add(&lp->list, &opened);
+	spin_unlock(&opened_lock);
+
+	return 0;
+out_close:
+	if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
+	lp->fd = -1;
+out:
+	spin_unlock(&lp->lock);
+	return err;
 }
 
 static int uml_net_close(struct net_device *dev)
@@ -161,9 +170,13 @@
 	if(lp->close != NULL)
 		(*lp->close)(lp->fd, &lp->user);
 	lp->fd = -1;
-	list_del(&lp->list);
 
 	spin_unlock(&lp->lock);
+
+	spin_lock(&opened_lock);
+	list_del(&lp->list);
+	spin_unlock(&opened_lock);
+
 	return 0;
 }
 
@@ -410,11 +423,7 @@
 	if (device->have_mac)
 		set_ether_mac(dev, device->mac);
 
-	spin_lock(&opened_lock);
-	list_add(&lp->list, &opened);
-	spin_unlock(&opened_lock);
-
-	return(0);
+	return 0;
 }
 
 static struct uml_net *find_device(int n)
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 4892e5f..83b688c 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -14,7 +14,7 @@
 extern void save_registers(int pid, union uml_pt_regs *regs);
 extern void restore_registers(int pid, union uml_pt_regs *regs);
 extern void init_registers(int pid);
-extern void get_safe_registers(unsigned long * regs);
+extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs);
 extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
 
 #endif
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
deleted file mode 100644
index eea1c9c4..0000000
--- a/arch/um/kernel/skas/process.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/* 
- * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <sched.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-#include <sys/time.h>
-#include <asm/unistd.h>
-#include <asm/types.h>
-#include "user.h"
-#include "ptrace_user.h"
-#include "sysdep/ptrace.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "skas.h"
-#include "stub-data.h"
-#include "mm_id.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/stub.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "skas_ptrace.h"
-#include "chan_user.h"
-#include "registers.h"
-#include "mem.h"
-#include "uml-config.h"
-#include "process.h"
-
-int is_skas_winch(int pid, int fd, void *data)
-{
-        if(pid != os_getpgrp())
-		return(0);
-
-	register_winch_irq(-1, fd, -1, data);
-	return(1);
-}
-
-void wait_stub_done(int pid, int sig, char * fname)
-{
-        int n, status, err;
-
-        do {
-                if ( sig != -1 ) {
-                        err = ptrace(PTRACE_CONT, pid, 0, sig);
-                        if(err)
-                                panic("%s : continue failed, errno = %d\n",
-                                      fname, errno);
-                }
-                sig = 0;
-
-                CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-        } while((n >= 0) && WIFSTOPPED(status) &&
-                ((WSTOPSIG(status) == SIGVTALRM) ||
-		 /* running UML inside a detached screen can cause
-		  * SIGWINCHes
-		  */
-		 (WSTOPSIG(status) == SIGWINCH)));
-
-        if((n < 0) || !WIFSTOPPED(status) ||
-           (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
-		unsigned long regs[HOST_FRAME_SIZE];
-		if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
-			printk("Failed to get registers from stub, "
-			       "errno = %d\n", errno);
-		else {
-			int i;
-
-			printk("Stub registers -\n");
-			for(i = 0; i < HOST_FRAME_SIZE; i++)
-				printk("\t%d - %lx\n", i, regs[i]);
-		}
-                panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
-                      "pid = %d, n = %d, errno = %d, status = 0x%x\n",
-                      fname, pid, n, errno, status);
-        }
-}
-
-void get_skas_faultinfo(int pid, struct faultinfo * fi)
-{
-        int err;
-
-        if(ptrace_faultinfo){
-                err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
-                if(err)
-                        panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
-                              "errno = %d\n", errno);
-
-                /* Special handling for i386, which has different structs */
-                if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
-                        memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
-                               sizeof(struct faultinfo) -
-                               sizeof(struct ptrace_faultinfo));
-        }
-        else {
-                wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
-
-                /* faultinfo is prepared by the stub-segv-handler at start of
-                 * the stub stack page. We just have to copy it.
-                 */
-                memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
-        }
-}
-
-static void handle_segv(int pid, union uml_pt_regs * regs)
-{
-        get_skas_faultinfo(pid, &regs->skas.faultinfo);
-        segv(regs->skas.faultinfo, 0, 1, NULL);
-}
-
-/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
-static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
-{
-	int err, status;
-
-	/* Mark this as a syscall */
-	UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs);
-
-	if (!local_using_sysemu)
-	{
-		err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
-		if(err < 0)
-			panic("handle_trap - nullifying syscall failed errno = %d\n",
-			      errno);
-
-		err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
-		if(err < 0)
-			panic("handle_trap - continuing to end of syscall failed, "
-			      "errno = %d\n", errno);
-
-		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
-		if((err < 0) || !WIFSTOPPED(status) ||
-		   (WSTOPSIG(status) != SIGTRAP + 0x80))
-			panic("handle_trap - failed to wait at end of syscall, "
-			      "errno = %d, status = %d\n", errno, status);
-	}
-
-	handle_syscall(regs);
-}
-
-extern int __syscall_stub_start;
-int stub_code_fd = -1;
-__u64 stub_code_offset;
-
-static int userspace_tramp(void *stack)
-{
-	void *addr;
-
-	ptrace(PTRACE_TRACEME, 0, 0, 0);
-
-	init_new_thread_signals(1);
-	enable_timer();
-
-	if(!proc_mm){
-		/* This has a pte, but it can't be mapped in with the usual
-		 * tlb_flush mechanism because this is part of that mechanism
-		 */
-		addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
-			      PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
-			      stub_code_fd, stub_code_offset);
-		if(addr == MAP_FAILED){
-			printk("mapping stub code failed, errno = %d\n",
-			       errno);
-			exit(1);
-		}
-
-		if(stack != NULL){
-			int fd;
-			__u64 offset;
-
-			fd = phys_mapping(to_phys(stack), &offset);
-			addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
-				    PROT_READ | PROT_WRITE,
-				    MAP_FIXED | MAP_SHARED, fd, offset);
-			if(addr == MAP_FAILED){
-				printk("mapping stub stack failed, "
-				       "errno = %d\n", errno);
-				exit(1);
-			}
-		}
-	}
-	if(!ptrace_faultinfo){
-		unsigned long v = UML_CONFIG_STUB_CODE +
-				  (unsigned long) stub_segv_handler -
-				  (unsigned long) &__syscall_stub_start;
-
-		set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
-		set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
-			    SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
-			    SIGUSR1, -1);
-	}
-
-	os_stop_process(os_getpid());
-	return(0);
-}
-
-/* Each element set once, and only accessed by a single processor anyway */
-#undef NR_CPUS
-#define NR_CPUS 1
-int userspace_pid[NR_CPUS];
-
-int start_userspace(unsigned long stub_stack)
-{
-	void *stack;
-	unsigned long sp;
-	int pid, status, n, flags;
-
-	if ( stub_code_fd == -1 )
-		stub_code_fd = phys_mapping(to_phys(&__syscall_stub_start),
-					    &stub_code_offset);
-
-	stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	if(stack == MAP_FAILED)
-		panic("start_userspace : mmap failed, errno = %d", errno);
-	sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
-
-	flags = CLONE_FILES | SIGCHLD;
-	if(proc_mm) flags |= CLONE_VM;
-	pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
-	if(pid < 0)
-		panic("start_userspace : clone failed, errno = %d", errno);
-
-	do {
-		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-		if(n < 0)
-			panic("start_userspace : wait failed, errno = %d", 
-			      errno);
-	} while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
-
-	if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
-		panic("start_userspace : expected SIGSTOP, got status = %d",
-		      status);
-
-	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
-		panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n",
-		      errno);
-
-	if(munmap(stack, PAGE_SIZE) < 0)
-		panic("start_userspace : munmap failed, errno = %d\n", errno);
-
-	return(pid);
-}
-
-void userspace(union uml_pt_regs *regs)
-{
-	int err, status, op, pid = userspace_pid[0];
-	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
-
-	while(1){
-		restore_registers(pid, regs);
-
-		/* Now we set local_using_sysemu to be used for one loop */
-		local_using_sysemu = get_using_sysemu();
-
-		op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
-
-		err = ptrace(op, pid, 0, 0);
-		if(err)
-			panic("userspace - could not resume userspace process, "
-			      "pid=%d, ptrace operation = %d, errno = %d\n",
-			      op, errno);
-
-		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
-		if(err < 0)
-			panic("userspace - waitpid failed, errno = %d\n", 
-			      errno);
-
-		regs->skas.is_user = 1;
-		save_registers(pid, regs);
-		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
-
-		if(WIFSTOPPED(status)){
-		  	switch(WSTOPSIG(status)){
-			case SIGSEGV:
-                                if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
-                                        user_signal(SIGSEGV, regs, pid);
-                                else handle_segv(pid, regs);
-				break;
-			case SIGTRAP + 0x80:
-			        handle_trap(pid, regs, local_using_sysemu);
-				break;
-			case SIGTRAP:
-				relay_signal(SIGTRAP, regs);
-				break;
-			case SIGIO:
-			case SIGVTALRM:
-			case SIGILL:
-			case SIGBUS:
-			case SIGFPE:
-			case SIGWINCH:
-                                user_signal(WSTOPSIG(status), regs, pid);
-				break;
-			default:
-			        printk("userspace - child stopped with signal "
-				       "%d\n", WSTOPSIG(status));
-			}
-			pid = userspace_pid[0];
-			interrupt_end();
-
-			/* Avoid -ERESTARTSYS handling in host */
-			PT_SYSCALL_NR(regs->skas.regs) = -1;
-		}
-	}
-}
-#define INIT_JMP_NEW_THREAD 0
-#define INIT_JMP_REMOVE_SIGSTACK 1
-#define INIT_JMP_CALLBACK 2
-#define INIT_JMP_HALT 3
-#define INIT_JMP_REBOOT 4
-
-
-int copy_context_skas0(unsigned long new_stack, int pid)
-{
-	int err;
-	unsigned long regs[MAX_REG_NR];
-	unsigned long current_stack = current_stub_stack();
-	struct stub_data *data = (struct stub_data *) current_stack;
-	struct stub_data *child_data = (struct stub_data *) new_stack;
-	__u64 new_offset;
-	int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
-
-	/* prepare offset and fd of child's stack as argument for parent's
-	 * and child's mmap2 calls
-	 */
-	*data = ((struct stub_data) { .offset	= MMAP_OFFSET(new_offset),
-				      .fd	= new_fd,
-				      .timer	= ((struct itimerval)
-					           { { 0, 1000000 / hz() },
-						     { 0, 1000000 / hz() }})});
-	get_safe_registers(regs);
-
-	/* Set parent's instruction pointer to start of clone-stub */
-	regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
-				(unsigned long) stub_clone_handler -
-				(unsigned long) &__syscall_stub_start;
-	regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
-		sizeof(void *);
-	err = ptrace_setregs(pid, regs);
-	if(err < 0)
-		panic("copy_context_skas0 : PTRACE_SETREGS failed, "
-		      "pid = %d, errno = %d\n", pid, errno);
-
-	/* set a well known return code for detection of child write failure */
-	child_data->err = 12345678;
-
-	/* Wait, until parent has finished its work: read child's pid from
-	 * parent's stack, and check, if bad result.
-	 */
-	wait_stub_done(pid, 0, "copy_context_skas0");
-
-	pid = data->err;
-	if(pid < 0)
-		panic("copy_context_skas0 - stub-parent reports error %d\n",
-		      pid);
-
-	/* Wait, until child has finished too: read child's result from
-	 * child's stack and check it.
-	 */
-	wait_stub_done(pid, -1, "copy_context_skas0");
-	if (child_data->err != UML_CONFIG_STUB_DATA)
-		panic("copy_context_skas0 - stub-child reports error %d\n",
-		      child_data->err);
-
-	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
-		   (void *)PTRACE_O_TRACESYSGOOD) < 0)
-		panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, "
-		      "errno = %d\n", errno);
-
-	return pid;
-}
-
-/*
- * This is used only, if stub pages are needed, while proc_mm is
- * availabl. Opening /proc/mm creates a new mm_context, which lacks
- * the stub-pages. Thus, we map them using /proc/mm-fd
- */
-void map_stub_pages(int fd, unsigned long code,
-		    unsigned long data, unsigned long stack)
-{
-	struct proc_mm_op mmop;
-	int n;
-
-	mmop = ((struct proc_mm_op) { .op        = MM_MMAP,
-				      .u         =
-				      { .mmap    =
-					{ .addr    = code,
-					  .len     = PAGE_SIZE,
-					  .prot    = PROT_EXEC,
-					  .flags   = MAP_FIXED | MAP_PRIVATE,
-					  .fd      = stub_code_fd,
-					  .offset  = stub_code_offset
-	} } });
-	n = os_write_file(fd, &mmop, sizeof(mmop));
-	if(n != sizeof(mmop))
-		panic("map_stub_pages : /proc/mm map for code failed, "
-		      "err = %d\n", -n);
-
-	if ( stack ) {
-		__u64 map_offset;
-		int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
-		mmop = ((struct proc_mm_op)
-				{ .op        = MM_MMAP,
-				  .u         =
-				  { .mmap    =
-				    { .addr    = data,
-				      .len     = PAGE_SIZE,
-				      .prot    = PROT_READ | PROT_WRITE,
-				      .flags   = MAP_FIXED | MAP_SHARED,
-				      .fd      = map_fd,
-				      .offset  = map_offset
-		} } });
-		n = os_write_file(fd, &mmop, sizeof(mmop));
-		if(n != sizeof(mmop))
-			panic("map_stub_pages : /proc/mm map for data failed, "
-			      "err = %d\n", -n);
-	}
-}
-
-void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
-		void (*handler)(int))
-{
-	unsigned long flags;
-	sigjmp_buf switch_buf, fork_buf;
-
-	*switch_buf_ptr = &switch_buf;
-	*fork_buf_ptr = &fork_buf;
-
-	/* Somewhat subtle - siglongjmp restores the signal mask before doing
-	 * the longjmp.  This means that when jumping from one stack to another
-	 * when the target stack has interrupts enabled, an interrupt may occur
-	 * on the source stack.  This is bad when starting up a process because
-	 * it's not supposed to get timer ticks until it has been scheduled.
-	 * So, we disable interrupts around the sigsetjmp to ensure that
-	 * they can't happen until we get back here where they are safe.
-	 */
-	flags = get_signals();
-	block_signals();
-	if(sigsetjmp(fork_buf, 1) == 0)
-		new_thread_proc(stack, handler);
-
-	remove_sigstack();
-
-	set_signals(flags);
-}
-
-void thread_wait(void *sw, void *fb)
-{
-	sigjmp_buf buf, **switch_buf = sw, *fork_buf;
-
-	*switch_buf = &buf;
-	fork_buf = fb;
-	if(sigsetjmp(buf, 1) == 0)
-		siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
-}
-
-void switch_threads(void *me, void *next)
-{
-	sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
-	
-	*me_ptr = &my_buf;
-	if(sigsetjmp(my_buf, 1) == 0)
-		siglongjmp(*next_buf, 1);
-}
-
-static sigjmp_buf initial_jmpbuf;
-
-/* XXX Make these percpu */
-static void (*cb_proc)(void *arg);
-static void *cb_arg;
-static sigjmp_buf *cb_back;
-
-int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
-{
-	sigjmp_buf **switch_buf = switch_buf_ptr;
-	int n;
-
-	set_handler(SIGWINCH, (__sighandler_t) sig_handler,
-		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
-		    SIGVTALRM, -1);
-
-	*fork_buf_ptr = &initial_jmpbuf;
-	n = sigsetjmp(initial_jmpbuf, 1);
-        switch(n){
-        case INIT_JMP_NEW_THREAD:
-                new_thread_proc((void *) stack, new_thread_handler);
-                break;
-        case INIT_JMP_REMOVE_SIGSTACK:
-                remove_sigstack();
-                break;
-        case INIT_JMP_CALLBACK:
-		(*cb_proc)(cb_arg);
-		siglongjmp(*cb_back, 1);
-                break;
-        case INIT_JMP_HALT:
-		kmalloc_ok = 0;
-		return(0);
-        case INIT_JMP_REBOOT:
-		kmalloc_ok = 0;
-		return(1);
-        default:
-                panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
-	}
-	siglongjmp(**switch_buf, 1);
-}
-
-void initial_thread_cb_skas(void (*proc)(void *), void *arg)
-{
-	sigjmp_buf here;
-
-	cb_proc = proc;
-	cb_arg = arg;
-	cb_back = &here;
-
-	block_signals();
-	if(sigsetjmp(here, 1) == 0)
-		siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
-	unblock_signals();
-
-	cb_proc = NULL;
-	cb_arg = NULL;
-	cb_back = NULL;
-}
-
-void halt_skas(void)
-{
-	block_signals();
-	siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
-}
-
-void reboot_skas(void)
-{
-	block_signals();
-	siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
-}
-
-void switch_mm_skas(struct mm_id *mm_idp)
-{
-	int err;
-
-#warning need cpu pid in switch_mm_skas
-	if(proc_mm){
-		err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
-			     mm_idp->u.mm_fd);
-		if(err)
-			panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
-			      "errno = %d\n", errno);
-	}
-	else userspace_pid[0] = mm_idp->u.pid;
-}
-
-/*
- * 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/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index e2d3ca4..27cdf91 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -193,6 +193,24 @@
 "        root=/dev/ubd5\n\n"
 );
 
+#ifndef CONFIG_MODE_TT
+
+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' and disable CONFIG_CMDLINE_ON_HOST if gdb \n");
+	printf("doesn't work as expected\n");
+
+	return 0;
+}
+
+__uml_setup("debug", no_skas_debug_setup,
+"debug\n"
+"    this flag is not needed to run gdb on UML in skas mode\n\n"
+);
+
+#endif
+
 #ifdef CONFIG_SMP
 static int __init uml_ncpus_setup(char *line, int *add)
 {
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 5294533..87c3aa0 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -122,6 +122,7 @@
 		return(-EINVAL);
 	}
 	*fd_out = ((int *) CMSG_DATA(cmsg))[0];
+	os_set_exec_close(*fd_out, 1);
 	return(0);
 }
 
@@ -137,7 +138,8 @@
 		return(err);
 
 	if(pri->fixed_config){
-		pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
+		pri->fd = os_open_file("/dev/net/tun",
+				       of_cloexec(of_rdwr(OPENFLAGS())), 0);
 		if(pri->fd < 0){
 			printk("Failed to open /dev/net/tun, err = %d\n",
 			       -pri->fd);
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 9890e90..fbb080c 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -60,7 +60,7 @@
 
 	multi_count++;
 
-	get_safe_registers(regs);
+	get_safe_registers(regs, NULL);
 	regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
 		((unsigned long) &batch_syscall_stub -
 		 (unsigned long) &__syscall_stub_start);
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 120a21c..bbf34cb 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -310,16 +310,12 @@
 		}
 	}
 }
-#define INIT_JMP_NEW_THREAD 0
-#define INIT_JMP_REMOVE_SIGSTACK 1
-#define INIT_JMP_CALLBACK 2
-#define INIT_JMP_HALT 3
-#define INIT_JMP_REBOOT 4
 
 int copy_context_skas0(unsigned long new_stack, int pid)
 {
 	int err;
-	unsigned long regs[MAX_REG_NR];
+	unsigned long regs[HOST_FRAME_SIZE];
+	unsigned long fp_regs[HOST_FP_SIZE];
 	unsigned long current_stack = current_stub_stack();
 	struct stub_data *data = (struct stub_data *) current_stack;
 	struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -334,7 +330,7 @@
 				      .timer    = ((struct itimerval)
 					            { { 0, 1000000 / hz() },
 						      { 0, 1000000 / hz() }})});
-	get_safe_registers(regs);
+	get_safe_registers(regs, fp_regs);
 
 	/* Set parent's instruction pointer to start of clone-stub */
 	regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
@@ -350,6 +346,11 @@
 		panic("copy_context_skas0 : PTRACE_SETREGS failed, "
 		      "pid = %d, errno = %d\n", pid, errno);
 
+	err = ptrace_setfpregs(pid, fp_regs);
+	if(err < 0)
+		panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
+		      "pid = %d, errno = %d\n", pid, errno);
+
 	/* set a well known return code for detection of child write failure */
 	child_data->err = 12345678;
 
@@ -457,6 +458,12 @@
 	set_signals(flags);
 }
 
+#define INIT_JMP_NEW_THREAD 0
+#define INIT_JMP_REMOVE_SIGSTACK 1
+#define INIT_JMP_CALLBACK 2
+#define INIT_JMP_HALT 3
+#define INIT_JMP_REBOOT 4
+
 void thread_wait(void *sw, void *fb)
 {
 	sigjmp_buf buf, **switch_buf = sw, *fork_buf;
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 6c5b17e..829d6b0 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -49,6 +49,7 @@
 	int pid = os_getpid(), ppid = getppid();
 	int sc_result;
 
+	change_sig(SIGWINCH, 0);
 	if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
 		perror("ptrace");
 		os_kill_process(pid, 0);
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index aee4812..7a6f6b9 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -122,9 +122,12 @@
 		      err);
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
 	memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+	if(fp_regs != NULL)
+		memcpy(fp_regs, exec_fp_regs,
+		       HOST_FP_SIZE * sizeof(unsigned long));
 }
 
 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 4b638dfb..001941f 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -70,9 +70,12 @@
 		      err);
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
 	memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+	if(fp_regs != NULL)
+		memcpy(fp_regs, exec_fp_regs,
+		       HOST_FP_SIZE * sizeof(unsigned long));
 }
 
 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c
index 12e404c..b5f9c33 100644
--- a/arch/um/sys-x86_64/ptrace_user.c
+++ b/arch/um/sys-x86_64/ptrace_user.c
@@ -24,6 +24,13 @@
 	return(0);
 }
 
+int ptrace_setfpregs(long pid, unsigned long *regs)
+{
+	if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
+		return -errno;
+	return 0;
+}
+
 void ptrace_pokeuser(unsigned long addr, unsigned long data)
 {
 	panic("ptrace_pokeuser");
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 5a585bf..7bd54a9 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -57,7 +57,7 @@
 #endif
 
 	DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
-	DEFINE(HOST_FP_SIZE, 0);
+	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);
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index fcb06a5..ea31b4c 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -2,13 +2,6 @@
 
 source "lib/Kconfig.debug"
 
-config INIT_DEBUG
-	bool "Debug __init statements"
-	depends on DEBUG_KERNEL
-	help
-	  Fill __init and __initdata at the end of boot. This helps debugging
-	  illegal uses of __init and __initdata after initialization.
-
 config DEBUG_RODATA
        bool "Write protect kernel read-only data structures"
        depends on DEBUG_KERNEL
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 09a3eb7..5683292 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-git12
-# Mon Jan 16 13:09:08 2006
+# Linux kernel version: 2.6.16-rc1-git2
+# Thu Jan 19 10:05:21 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -310,6 +310,11 @@
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -319,11 +324,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -1098,6 +1098,12 @@
 #
 
 #
+# EDAC - error detection and reporting (RAS)
+#
+# CONFIG_EDAC is not set
+# CONFIG_EDAC_POLL is not set
+
+#
 # Firmware Drivers
 #
 # CONFIG_EDD is not set
@@ -1290,6 +1296,7 @@
 # CONFIG_DEBUG_VM is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_UNWIND_INFO is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_INIT_DEBUG=y
 # CONFIG_DEBUG_RODATA is not set
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 5d3c5b0..6147770 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -35,8 +35,12 @@
 #include <asm/mach_apic.h>
 #include <asm/nmi.h>
 #include <asm/idle.h>
+#include <asm/proto.h>
+#include <asm/timex.h>
 
 int apic_verbosity;
+int apic_runs_main_timer;
+int apic_calibrate_pmtmr __initdata;
 
 int disable_apic_timer __initdata;
 
@@ -68,6 +72,26 @@
 	return maxlvt;
 }
 
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+	printk("unexpected IRQ trap at vector %02x\n", irq);
+	/*
+	 * Currently unexpected vectors happen only on SMP and APIC.
+	 * We _must_ ack these because every local APIC has only N
+	 * irq slots per priority level, and a 'hanging, unacked' IRQ
+	 * holds up an irq slot - in excessive cases (when multiple
+	 * unexpected vectors occur) that might lock up the APIC
+	 * completely.
+  	 * But don't ack when the APIC is disabled. -AK
+	 */
+	if (!disable_apic)
+		ack_APIC_irq();
+}
+
 void clear_local_APIC(void)
 {
 	int maxlvt;
@@ -702,9 +726,17 @@
 			c2 |= inb_p(0x40) << 8;
 		} while (c2 - c1 < 300);
 	}
-
 	__setup_APIC_LVTT(clocks);
-
+	/* Turn off PIT interrupt if we use APIC timer as main timer.
+	   Only works with the PM timer right now
+	   TBD fix it for HPET too. */
+	if (vxtime.mode == VXTIME_PMTMR &&
+		smp_processor_id() == boot_cpu_id &&
+		apic_runs_main_timer == 1 &&
+		!cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) {
+		stop_timer_interrupt();
+		apic_runs_main_timer++;
+	}
 	local_irq_restore(flags);
 }
 
@@ -735,14 +767,27 @@
 	__setup_APIC_LVTT(1000000000);
 
 	apic_start = apic_read(APIC_TMCCT);
-	rdtscl(tsc_start);
-
-	do {
+#ifdef CONFIG_X86_PM_TIMER
+	if (apic_calibrate_pmtmr && pmtmr_ioport) {
+		pmtimer_wait(5000);  /* 5ms wait */
 		apic = apic_read(APIC_TMCCT);
-		rdtscl(tsc);
-	} while ((tsc - tsc_start) < TICK_COUNT && (apic - apic_start) < TICK_COUNT);
+		result = (apic_start - apic) * 1000L / 5;
+	} else
+#endif
+	{
+		rdtscl(tsc_start);
 
-	result = (apic_start - apic) * 1000L * cpu_khz / (tsc - tsc_start);
+		do {
+			apic = apic_read(APIC_TMCCT);
+			rdtscl(tsc);
+		} while ((tsc - tsc_start) < TICK_COUNT &&
+				(apic - apic_start) < TICK_COUNT);
+
+		result = (apic_start - apic) * 1000L * cpu_khz /
+					(tsc - tsc_start);
+	}
+	printk("result %d\n", result);
+
 
 	printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
 		result / 1000 / 1000, result / 1000 % 1000);
@@ -872,6 +917,8 @@
 #ifdef CONFIG_SMP
 	update_process_times(user_mode(regs));
 #endif
+	if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id)
+		main_timer_handler(regs);
 	/*
 	 * We take the 'long' return path, and there every subsystem
 	 * grabs the appropriate locks (kernel lock/ irq lock).
@@ -924,7 +971,7 @@
  * multi-chassis. Use available data to take a good guess.
  * If in doubt, go HPET.
  */
-__init int oem_force_hpet_timer(void)
+__cpuinit int oem_force_hpet_timer(void)
 {
 	int i, clusters, zeros;
 	unsigned id;
@@ -1081,10 +1128,34 @@
 
 static __init int setup_noapictimer(char *str) 
 { 
+	if (str[0] != ' ' && str[0] != 0)
+		return -1;
 	disable_apic_timer = 1;
 	return 0;
 } 
 
+static __init int setup_apicmaintimer(char *str)
+{
+	apic_runs_main_timer = 1;
+	nohpet = 1;
+	return 0;
+}
+__setup("apicmaintimer", setup_apicmaintimer);
+
+static __init int setup_noapicmaintimer(char *str)
+{
+	apic_runs_main_timer = -1;
+	return 0;
+}
+__setup("noapicmaintimer", setup_noapicmaintimer);
+
+static __init int setup_apicpmtimer(char *s)
+{
+	apic_calibrate_pmtmr = 1;
+	return setup_apicmaintimer(NULL);
+}
+__setup("apicpmtimer", setup_apicpmtimer);
+
 /* dummy parsing: see setup.c */
 
 __setup("disableapic", setup_disableapic); 
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index dbdba56..b150c87 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -499,7 +499,9 @@
 	movq %gs:pda_irqstackptr,%rax
 	cmoveq %rax,%rsp /*todo This needs CFI annotation! */
 	pushq %rdi			# save old stack	
+#ifndef CONFIG_DEBUG_INFO
 	CFI_ADJUST_CFA_OFFSET	8
+#endif
 	call \func
 	.endm
 
@@ -509,7 +511,9 @@
 	/* 0(%rsp): oldrsp-ARGOFFSET */
 ret_from_intr:
 	popq  %rdi
+#ifndef CONFIG_DEBUG_INFO
 	CFI_ADJUST_CFA_OFFSET	-8
+#endif
 	cli	
 	decl %gs:pda_irqcount
 #ifdef CONFIG_DEBUG_INFO
@@ -922,7 +926,7 @@
 	.previous .text
 
 	/* runs on exception stack */	
-ENTRY(nmi)
+KPROBE_ENTRY(nmi)
 	INTR_FRAME
 	pushq $-1
 	CFI_ADJUST_CFA_OFFSET 8
@@ -969,6 +973,7 @@
 	cli
 	jmp paranoid_userspace
 	CFI_ENDPROC
+	.previous .text
 
 KPROBE_ENTRY(int3)
  	INTR_FRAME
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 1a5060b..4282d72 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -304,6 +304,14 @@
 #endif
 					/* RED-PEN skip them on mptables too? */
 					return;
+				case PCI_VENDOR_ID_ATI:
+					if (apic_runs_main_timer != 0)
+						break;
+					printk(KERN_INFO
+	     "ATI board detected. Using APIC/PM timer.\n");
+					apic_runs_main_timer = 1;
+					nohpet = 1;
+					return;
 				} 
 
 				/* No multi-function device? */
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 13a2ead..b8b9529 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -380,7 +380,7 @@
  */
 void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
 {
-	static cpumask_t mce_cpus __initdata = CPU_MASK_NONE;
+	static cpumask_t mce_cpus = CPU_MASK_NONE;
 
 	mce_cpu_quirks(c); 
 
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 5fae6f0..8be407a 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -24,6 +24,7 @@
 #include <linux/sysdev.h>
 #include <linux/nmi.h>
 #include <linux/sysctl.h>
+#include <linux/kprobes.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -468,7 +469,7 @@
  	touch_softlockup_watchdog();
 }
 
-void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason)
+void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
 {
 	int sum;
 	int touched = 0;
@@ -512,14 +513,14 @@
 	}
 }
 
-static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
+static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu)
 {
 	return 0;
 }
  
 static nmi_callback_t nmi_callback = dummy_nmi_callback;
  
-asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
+asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 {
 	int cpu = safe_smp_processor_id();
 
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index 2f5d832..4ed391e 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -107,6 +107,9 @@
 				goto again;
 			}
 
+			/* Let low level make its own zone decisions */
+			gfp &= ~(GFP_DMA32|GFP_DMA);
+
 			if (dma_ops->alloc_coherent)
 				return dma_ops->alloc_coherent(dev, size,
 							   dma_handle, gfp);
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index c37fc77..2fe23a6 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -457,9 +457,12 @@
 error:
 	flush_gart(NULL);
 	gart_unmap_sg(dev, sg, nents, dir);
-	/* When it was forced try again unforced */
-	if (force_iommu) 
-		return dma_map_sg_nonforce(dev, sg, nents, dir);
+	/* When it was forced or merged try again in a dumb way */
+	if (force_iommu || iommu_merge) {
+		out = dma_map_sg_nonforce(dev, sg, nents, dir);
+		if (out > 0)
+			return out;
+	}
 	if (panic_on_overflow)
 		panic("dma_map_sg: overflow on %lu pages\n", pages);
 	iommu_full(dev, pages << PAGE_SHIFT, dir);
@@ -642,9 +645,18 @@
 	    (no_agp && init_k8_gatt(&info) < 0)) {
 		no_iommu = 1;
 		no_iommu_init();
+		printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
+		if (end_pfn > MAX_DMA32_PFN) {
+			printk(KERN_ERR "WARNING more than 4GB of memory "
+					"but IOMMU not compiled in.\n"
+			       KERN_ERR "WARNING 32bit PCI may malfunction.\n"
+			       KERN_ERR "You might want to enable "
+					"CONFIG_GART_IOMMU\n");
+		}
 		return -1;
 	}
 
+	printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
 	aper_size = info.aper_size * 1024 * 1024;	
 	iommu_size = check_iommu_size(info.aper_base, aper_size); 
 	iommu_pages = iommu_size >> PAGE_SHIFT; 
@@ -718,7 +730,6 @@
 		     
 	flush_gart(NULL);
 
-	printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
 	dma_ops = &gart_dma_ops;
 
 	return 0;
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c
index e415649..44adcc2 100644
--- a/arch/x86_64/kernel/pci-nommu.c
+++ b/arch/x86_64/kernel/pci-nommu.c
@@ -88,12 +88,5 @@
 {
 	if (dma_ops)
 		return;
-	printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
 	dma_ops = &nommu_dma_ops;
-	if (end_pfn > MAX_DMA32_PFN) {
-		printk(KERN_ERR
-		       "WARNING more than 4GB of memory but IOMMU not compiled in.\n"
-		       KERN_ERR "WARNING 32bit PCI may malfunction.\n"
-		       KERN_ERR "You might want to enable CONFIG_GART_IOMMU\n");
-	}
 }
diff --git a/arch/x86_64/kernel/pci-swiotlb.c b/arch/x86_64/kernel/pci-swiotlb.c
index 3569a25..990ed67 100644
--- a/arch/x86_64/kernel/pci-swiotlb.c
+++ b/arch/x86_64/kernel/pci-swiotlb.c
@@ -35,8 +35,8 @@
 	    (end_pfn > MAX_DMA32_PFN || force_iommu))
 	       swiotlb = 1;
 	if (swiotlb) {
-		swiotlb_init();
 		printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
+		swiotlb_init();
 		dma_ops = &swiotlb_dma_ops;
 	}
 }
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c
index feb5f10..5c51d10 100644
--- a/arch/x86_64/kernel/pmtimer.c
+++ b/arch/x86_64/kernel/pmtimer.c
@@ -80,6 +80,31 @@
 	return lost - 1;
 }
 
+static unsigned pmtimer_wait_tick(void)
+{
+	u32 a, b;
+	for (a = b = inl(pmtmr_ioport) & ACPI_PM_MASK;
+	     a == b;
+	     b = inl(pmtmr_ioport) & ACPI_PM_MASK)
+		;
+	return b;
+}
+
+/* note: wait time is rounded up to one tick */
+void pmtimer_wait(unsigned us)
+{
+	u32 a, b;
+	a = pmtimer_wait_tick();
+	do {
+		b = inl(pmtmr_ioport);
+	} while (cyc2us(b - a) < us);
+}
+
+void pmtimer_resume(void)
+{
+	last_pmtmr_tick = inl(pmtmr_ioport);
+}
+
 unsigned int do_gettimeoffset_pm(void)
 {
 	u32 now, offset, delta = 0;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 8ded407..22a05de 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -516,8 +516,10 @@
  * This could still be optimized: 
  * - fold all the options into a flag word and test it with a single test.
  * - could test fs/gs bitsliced
+ *
+ * Kprobes not supported here. Set the probe on schedule instead.
  */
-struct task_struct *
+__kprobes struct task_struct *
 __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
 	struct thread_struct *prev = &prev_p->thread,
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 28895c0..9435ab7 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -94,7 +94,6 @@
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
 struct screen_info screen_info;
 struct sys_desc_table_struct {
 	unsigned short length;
@@ -572,7 +571,6 @@
 	unsigned long kernel_end;
 
  	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
- 	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
 	edid_info = EDID_INFO;
 	saved_video_mode = SAVED_VIDEO_MODE;
@@ -741,7 +739,7 @@
 	e820_setup_gap();
 
 #ifdef CONFIG_GART_IOMMU
-       iommu_hole_init();
+	iommu_hole_init();
 #endif
 
 #ifdef CONFIG_VT
@@ -877,6 +875,7 @@
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
 	int r;
+	unsigned level;
 
 #ifdef CONFIG_SMP
 	unsigned long value;
@@ -899,6 +898,11 @@
 	   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
 	clear_bit(0*32+31, &c->x86_capability);
 	
+	/* On C+ stepping K8 rep microcode works well for copy/memset */
+	level = cpuid_eax(1);
+	if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
+		set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
+
 	r = get_model_name(c);
 	if (!r) { 
 		switch (c->x86) { 
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index a28756e..67e4e28 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -59,6 +59,7 @@
 #include <asm/nmi.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
+#include <asm/numa.h>
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
@@ -890,6 +891,7 @@
 	if (boot_error) {
 		cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
 		clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+		clear_node_cpumask(cpu); /* was set by numa_add_cpu */
 		cpu_clear(cpu, cpu_present_map);
 		cpu_clear(cpu, cpu_possible_map);
 		x86_cpu_to_apicid[cpu] = BAD_APICID;
@@ -1187,6 +1189,7 @@
 	cpu_clear(cpu, cpu_callout_map);
 	cpu_clear(cpu, cpu_callin_map);
 	clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+	clear_node_cpumask(cpu);
 }
 
 int __cpu_disable(void)
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index f8c47c6..dba7237 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -51,7 +51,7 @@
 DEFINE_SPINLOCK(rtc_lock);
 DEFINE_SPINLOCK(i8253_lock);
 
-static int nohpet __initdata = 0;
+int nohpet __initdata = 0;
 static int notsc __initdata = 0;
 
 #undef HPET_HACK_ENABLE_DANGEROUS
@@ -345,7 +345,7 @@
 #endif
 }
 
-static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void main_timer_handler(struct pt_regs *regs)
 {
 	static unsigned long rtc_update = 0;
 	unsigned long tsc;
@@ -458,12 +458,17 @@
 	}
  
 	write_sequnlock(&xtime_lock);
+}
 
+static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (apic_runs_main_timer > 1)
+		return IRQ_HANDLED;
+	main_timer_handler(regs);
 #ifdef CONFIG_X86_LOCAL_APIC
 	if (using_apic_timer)
 		smp_send_timer_broadcast_ipi();
 #endif
-
 	return IRQ_HANDLED;
 }
 
@@ -743,7 +748,7 @@
 	 * Timer0 and Timer1 is used by platform.
 	 */
 	hd.hd_phys_address = vxtime.hpet_address;
-	hd.hd_address = (void *)fix_to_virt(FIX_HPET_BASE);
+	hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
 	hd.hd_nirqs = ntimer;
 	hd.hd_flags = HPET_DATA_PLATFORM;
 	hpet_reserve_timer(&hd, 0);
@@ -843,17 +848,43 @@
 	return hpet_timer_stop_set_go(hpet_tick);
 }
 
-void __init pit_init(void)
+#define PIT_MODE 0x43
+#define PIT_CH0  0x40
+
+static void __init __pit_init(int val, u8 mode)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&i8253_lock, flags);
-	outb_p(0x34, 0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
-	outb_p(LATCH & 0xff, 0x40);	/* LSB */
-	outb_p(LATCH >> 8, 0x40);	/* MSB */
+	outb_p(mode, PIT_MODE);
+	outb_p(val & 0xff, PIT_CH0);	/* LSB */
+	outb_p(val >> 8, PIT_CH0);	/* MSB */
 	spin_unlock_irqrestore(&i8253_lock, flags);
 }
 
+void __init pit_init(void)
+{
+	__pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
+}
+
+void __init pit_stop_interrupt(void)
+{
+	__pit_init(0, 0x30); /* mode 0 */
+}
+
+void __init stop_timer_interrupt(void)
+{
+	char *name;
+	if (vxtime.hpet_address) {
+		name = "HPET";
+		hpet_timer_stop_set_go(0);
+	} else {
+		name = "PIT";
+		pit_stop_interrupt();
+	}
+	printk(KERN_INFO "timer: %s interrupt stopped.\n", name);
+}
+
 int __init time_setup(char *str)
 {
 	report_lost_ticks = 1;
@@ -932,7 +963,7 @@
  * Make an educated guess if the TSC is trustworthy and synchronized
  * over all CPUs.
  */
-__init int unsynchronized_tsc(void)
+__cpuinit int unsynchronized_tsc(void)
 {
 #ifdef CONFIG_SMP
 	if (oem_force_hpet_timer())
@@ -1016,9 +1047,21 @@
 	write_seqlock_irqsave(&xtime_lock,flags);
 	xtime.tv_sec = sec;
 	xtime.tv_nsec = 0;
+	if (vxtime.mode == VXTIME_HPET) {
+		if (hpet_use_timer)
+			vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
+		else
+			vxtime.last = hpet_readl(HPET_COUNTER);
+#ifdef CONFIG_X86_PM_TIMER
+	} else if (vxtime.mode == VXTIME_PMTMR) {
+		pmtimer_resume();
+#endif
+	} else
+		vxtime.last_tsc = get_cycles_sync();
 	write_sequnlock_irqrestore(&xtime_lock,flags);
 	jiffies += sleep_length;
 	wall_jiffies += sleep_length;
+	monotonic_base += sleep_length * (NSEC_PER_SEC/HZ);
 	touch_softlockup_watchdog();
 	return 0;
 }
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 8bb0aed..ee1b2da 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -372,7 +372,7 @@
 static DEFINE_SPINLOCK(die_lock);
 static int die_owner = -1;
 
-unsigned long oops_begin(void)
+unsigned __kprobes long oops_begin(void)
 {
 	int cpu = safe_smp_processor_id();
 	unsigned long flags;
@@ -391,7 +391,7 @@
 	return flags;
 }
 
-void oops_end(unsigned long flags)
+void __kprobes oops_end(unsigned long flags)
 { 
 	die_owner = -1;
 	bust_spinlocks(0);
@@ -400,7 +400,7 @@
 		panic("Oops");
 }
 
-void __die(const char * str, struct pt_regs * regs, long err)
+void __kprobes __die(const char * str, struct pt_regs * regs, long err)
 {
 	static int die_counter;
 	printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
@@ -432,7 +432,7 @@
 	do_exit(SIGSEGV); 
 }
 
-void die_nmi(char *str, struct pt_regs *regs)
+void __kprobes die_nmi(char *str, struct pt_regs *regs)
 {
 	unsigned long flags = oops_begin();
 
@@ -575,7 +575,8 @@
 	}
 }
 
-static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+mem_parity_error(unsigned char reason, struct pt_regs * regs)
 {
 	printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
 	printk("You probably have a hardware problem with your RAM chips\n");
@@ -585,7 +586,8 @@
 	outb(reason, 0x61);
 }
 
-static void io_check_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+io_check_error(unsigned char reason, struct pt_regs * regs)
 {
 	printk("NMI: IOCK error (debug interrupt?)\n");
 	show_registers(regs);
@@ -598,7 +600,8 @@
 	outb(reason, 0x61);
 }
 
-static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
 {	printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
 	printk("Dazed and confused, but trying to continue\n");
 	printk("Do you have a strange power saving mode enabled?\n");
@@ -606,7 +609,7 @@
 
 /* Runs on IST stack. This code must keep interrupts off all the time.
    Nested NMIs are prevented by the CPU. */
-asmlinkage void default_do_nmi(struct pt_regs *regs)
+asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
 {
 	unsigned char reason = 0;
 	int cpu;
@@ -658,7 +661,7 @@
 /* Help handler running on IST stack to switch back to user stack
    for scheduling or signal handling. The actual stack switch is done in
    entry.S */
-asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs)
+asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
 {
 	struct pt_regs *regs = eregs;
 	/* Did already sync */
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index b0eed1f..74db006 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -172,13 +172,15 @@
   . = ALIGN(4096);
   __initramfs_start = .;
   .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
-  __initramfs_end = .;	
-  . = ALIGN(32);
+  __initramfs_end = .;
+  /* temporary here to work around NR_CPUS. If you see this comment in 2.6.17+
+   complain */
+  . = ALIGN(4096);	
+  __init_end = .;	
+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
   __per_cpu_start = .;
   .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
   __per_cpu_end = .;
-  . = ALIGN(4096);
-  __init_end = .;
 
   . = ALIGN(4096);
   __nosave_begin = .;
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index b614d54..3496abc 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -39,11 +39,6 @@
 extern void __read_lock_failed(rwlock_t *rw);
 #endif
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
 //EXPORT_SYMBOL(dump_fpu);
diff --git a/arch/x86_64/lib/clear_page.S b/arch/x86_64/lib/clear_page.S
index 43d9fa1..1f81b79 100644
--- a/arch/x86_64/lib/clear_page.S
+++ b/arch/x86_64/lib/clear_page.S
@@ -5,8 +5,46 @@
 	.globl clear_page
 	.p2align 4
 clear_page:
+	xorl   %eax,%eax
+	movl   $4096/64,%ecx
+	.p2align 4
+.Lloop:
+	decl	%ecx
+#define PUT(x) movq %rax,x*8(%rdi)
+	movq %rax,(%rdi)
+	PUT(1)
+	PUT(2)
+	PUT(3)
+	PUT(4)
+	PUT(5)
+	PUT(6)
+	PUT(7)
+	leaq	64(%rdi),%rdi
+	jnz	.Lloop
+	nop
+	ret
+clear_page_end:
+
+	/* Some CPUs run faster using the string instructions.
+	   It is also a lot simpler. Use this when possible */
+
+#include <asm/cpufeature.h>
+
+	.section .altinstructions,"a"
+	.align 8
+	.quad  clear_page
+	.quad  clear_page_c
+	.byte  X86_FEATURE_REP_GOOD
+	.byte  clear_page_end-clear_page
+	.byte  clear_page_c_end-clear_page_c
+	.previous
+
+	.section .altinstr_replacement,"ax"
+clear_page_c:
 	movl $4096/8,%ecx
 	xorl %eax,%eax
 	rep 
 	stosq
 	ret
+clear_page_c_end:
+	.previous
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S
index 621a197..8fa19d9 100644
--- a/arch/x86_64/lib/copy_page.S
+++ b/arch/x86_64/lib/copy_page.S
@@ -8,7 +8,94 @@
 	.globl copy_page
 	.p2align 4
 copy_page:
+	subq	$3*8,%rsp
+	movq	%rbx,(%rsp)
+	movq	%r12,1*8(%rsp)
+	movq	%r13,2*8(%rsp)
+
+	movl	$(4096/64)-5,%ecx
+	.p2align 4
+.Loop64:
+  	dec     %rcx
+
+	movq        (%rsi), %rax
+	movq      8 (%rsi), %rbx
+	movq     16 (%rsi), %rdx
+	movq     24 (%rsi), %r8
+	movq     32 (%rsi), %r9
+	movq     40 (%rsi), %r10
+	movq     48 (%rsi), %r11
+	movq     56 (%rsi), %r12
+
+	prefetcht0 5*64(%rsi)
+
+	movq     %rax,    (%rdi)
+	movq     %rbx,  8 (%rdi)
+	movq     %rdx, 16 (%rdi)
+	movq     %r8,  24 (%rdi)
+	movq     %r9,  32 (%rdi)
+	movq     %r10, 40 (%rdi)
+	movq     %r11, 48 (%rdi)
+	movq     %r12, 56 (%rdi)
+
+	leaq    64 (%rsi), %rsi
+	leaq    64 (%rdi), %rdi
+
+	jnz     .Loop64
+
+	movl	$5,%ecx
+	.p2align 4
+.Loop2:
+	decl   %ecx
+
+	movq        (%rsi), %rax
+	movq      8 (%rsi), %rbx
+	movq     16 (%rsi), %rdx
+	movq     24 (%rsi), %r8
+	movq     32 (%rsi), %r9
+	movq     40 (%rsi), %r10
+	movq     48 (%rsi), %r11
+	movq     56 (%rsi), %r12
+
+	movq     %rax,    (%rdi)
+	movq     %rbx,  8 (%rdi)
+	movq     %rdx, 16 (%rdi)
+	movq     %r8,  24 (%rdi)
+	movq     %r9,  32 (%rdi)
+	movq     %r10, 40 (%rdi)
+	movq     %r11, 48 (%rdi)
+	movq     %r12, 56 (%rdi)
+
+	leaq	64(%rdi),%rdi
+	leaq	64(%rsi),%rsi
+
+	jnz	.Loop2
+
+	movq	(%rsp),%rbx
+	movq	1*8(%rsp),%r12
+	movq	2*8(%rsp),%r13
+	addq	$3*8,%rsp
+	ret
+
+	/* Some CPUs run faster using the string copy instructions.
+	   It is also a lot simpler. Use this when possible */
+
+#include <asm/cpufeature.h>
+
+	.section .altinstructions,"a"
+	.align 8
+	.quad  copy_page
+	.quad  copy_page_c
+	.byte  X86_FEATURE_REP_GOOD
+	.byte  copy_page_c_end-copy_page_c
+	.byte  copy_page_c_end-copy_page_c
+	.previous
+
+	.section .altinstr_replacement,"ax"
+copy_page_c:
 	movl $4096/8,%ecx
 	rep 
 	movsq 
 	ret
+copy_page_c_end:
+	.previous
diff --git a/arch/x86_64/lib/copy_user.S b/arch/x86_64/lib/copy_user.S
index 79422b6..f64569b 100644
--- a/arch/x86_64/lib/copy_user.S
+++ b/arch/x86_64/lib/copy_user.S
@@ -4,9 +4,12 @@
  * Functions to copy from and to user space.		
  */		 
 
+#define FIX_ALIGNMENT 1
+
 	#include <asm/current.h>
 	#include <asm/asm-offsets.h>
 	#include <asm/thread_info.h>
+	#include <asm/cpufeature.h>
 
 /* Standard copy_to_user with segment limit checking */		
 	.globl copy_to_user
@@ -18,7 +21,23 @@
 	jc  bad_to_user
 	cmpq threadinfo_addr_limit(%rax),%rcx
 	jae bad_to_user
-	jmp copy_user_generic
+2:
+	.byte 0xe9	/* 32bit jump */
+	.long .Lcug-1f
+1:
+
+	.section .altinstr_replacement,"ax"
+3:	.byte 0xe9			/* replacement jmp with 8 bit immediate */
+	.long copy_user_generic_c-1b	/* offset */
+	.previous
+	.section .altinstructions,"a"
+	.align 8
+	.quad  2b
+	.quad  3b
+	.byte  X86_FEATURE_REP_GOOD
+	.byte  5
+	.byte  5
+	.previous
 
 /* Standard copy_from_user with segment limit checking */	
 	.globl copy_from_user
@@ -53,44 +72,230 @@
  * rsi source
  * rdx count
  *
- * Only 4GB of copy is supported. This shouldn't be a problem
- * because the kernel normally only writes from/to page sized chunks
- * even if user space passed a longer buffer.
- * And more would be dangerous because both Intel and AMD have
- * errata with rep movsq > 4GB. If someone feels the need to fix
- * this please consider this.
- *
  * Output:		
  * eax uncopied bytes or 0 if successful.
  */
-
 	.globl copy_user_generic
+	.p2align 4
 copy_user_generic:
+	.byte 0x66,0x66,0x90	/* 5 byte nop for replacement jump */
+	.byte 0x66,0x90
+1:
+	.section .altinstr_replacement,"ax"
+2:	.byte 0xe9	             /* near jump with 32bit immediate */
+	.long copy_user_generic_c-1b /* offset */
+	.previous
+	.section .altinstructions,"a"
+	.align 8
+	.quad  copy_user_generic
+	.quad  2b
+	.byte  X86_FEATURE_REP_GOOD
+	.byte  5
+	.byte  5
+	.previous
+.Lcug:
+	pushq %rbx
+	xorl %eax,%eax		/*zero for the exception handler */
+
+#ifdef FIX_ALIGNMENT
+	/* check for bad alignment of destination */
+	movl %edi,%ecx
+	andl $7,%ecx
+	jnz  .Lbad_alignment
+.Lafter_bad_alignment:
+#endif
+
+	movq %rdx,%rcx
+
+	movl $64,%ebx
+	shrq $6,%rdx
+	decq %rdx
+	js   .Lhandle_tail
+
+	.p2align 4
+.Lloop:
+.Ls1:	movq (%rsi),%r11
+.Ls2:	movq 1*8(%rsi),%r8
+.Ls3:	movq 2*8(%rsi),%r9
+.Ls4:	movq 3*8(%rsi),%r10
+.Ld1:	movq %r11,(%rdi)
+.Ld2:	movq %r8,1*8(%rdi)
+.Ld3:	movq %r9,2*8(%rdi)
+.Ld4:	movq %r10,3*8(%rdi)
+
+.Ls5:	movq 4*8(%rsi),%r11
+.Ls6:	movq 5*8(%rsi),%r8
+.Ls7:	movq 6*8(%rsi),%r9
+.Ls8:	movq 7*8(%rsi),%r10
+.Ld5:	movq %r11,4*8(%rdi)
+.Ld6:	movq %r8,5*8(%rdi)
+.Ld7:	movq %r9,6*8(%rdi)
+.Ld8:	movq %r10,7*8(%rdi)
+
+	decq %rdx
+
+	leaq 64(%rsi),%rsi
+	leaq 64(%rdi),%rdi
+
+	jns  .Lloop
+
+	.p2align 4
+.Lhandle_tail:
+	movl %ecx,%edx
+	andl $63,%ecx
+	shrl $3,%ecx
+	jz   .Lhandle_7
+	movl $8,%ebx
+	.p2align 4
+.Lloop_8:
+.Ls9:	movq (%rsi),%r8
+.Ld9:	movq %r8,(%rdi)
+	decl %ecx
+	leaq 8(%rdi),%rdi
+	leaq 8(%rsi),%rsi
+	jnz .Lloop_8
+
+.Lhandle_7:
+	movl %edx,%ecx
+	andl $7,%ecx
+	jz   .Lende
+	.p2align 4
+.Lloop_1:
+.Ls10:	movb (%rsi),%bl
+.Ld10:	movb %bl,(%rdi)
+	incq %rdi
+	incq %rsi
+	decl %ecx
+	jnz .Lloop_1
+
+.Lende:
+	popq %rbx
+	ret
+
+#ifdef FIX_ALIGNMENT
+	/* align destination */
+	.p2align 4
+.Lbad_alignment:
+	movl $8,%r9d
+	subl %ecx,%r9d
+	movl %r9d,%ecx
+	cmpq %r9,%rdx
+	jz   .Lhandle_7
+	js   .Lhandle_7
+.Lalign_1:
+.Ls11:	movb (%rsi),%bl
+.Ld11:	movb %bl,(%rdi)
+	incq %rsi
+	incq %rdi
+	decl %ecx
+	jnz .Lalign_1
+	subq %r9,%rdx
+	jmp .Lafter_bad_alignment
+#endif
+
+	/* table sorted by exception address */
+	.section __ex_table,"a"
+	.align 8
+	.quad .Ls1,.Ls1e
+	.quad .Ls2,.Ls2e
+	.quad .Ls3,.Ls3e
+	.quad .Ls4,.Ls4e
+	.quad .Ld1,.Ls1e
+	.quad .Ld2,.Ls2e
+	.quad .Ld3,.Ls3e
+	.quad .Ld4,.Ls4e
+	.quad .Ls5,.Ls5e
+	.quad .Ls6,.Ls6e
+	.quad .Ls7,.Ls7e
+	.quad .Ls8,.Ls8e
+	.quad .Ld5,.Ls5e
+	.quad .Ld6,.Ls6e
+	.quad .Ld7,.Ls7e
+	.quad .Ld8,.Ls8e
+	.quad .Ls9,.Le_quad
+	.quad .Ld9,.Le_quad
+	.quad .Ls10,.Le_byte
+	.quad .Ld10,.Le_byte
+#ifdef FIX_ALIGNMENT
+	.quad .Ls11,.Lzero_rest
+	.quad .Ld11,.Lzero_rest
+#endif
+	.quad .Le5,.Le_zero
+	.previous
+
+	/* compute 64-offset for main loop. 8 bytes accuracy with error on the
+	   pessimistic side. this is gross. it would be better to fix the
+	   interface. */
+	/* eax: zero, ebx: 64 */
+.Ls1e: 	addl $8,%eax
+.Ls2e: 	addl $8,%eax
+.Ls3e: 	addl $8,%eax
+.Ls4e: 	addl $8,%eax
+.Ls5e: 	addl $8,%eax
+.Ls6e: 	addl $8,%eax
+.Ls7e: 	addl $8,%eax
+.Ls8e: 	addl $8,%eax
+	addq %rbx,%rdi	/* +64 */
+	subq %rax,%rdi  /* correct destination with computed offset */
+
+	shlq $6,%rdx	/* loop counter * 64 (stride length) */
+	addq %rax,%rdx	/* add offset to loopcnt */
+	andl $63,%ecx	/* remaining bytes */
+	addq %rcx,%rdx	/* add them */
+	jmp .Lzero_rest
+
+	/* exception on quad word loop in tail handling */
+	/* ecx:	loopcnt/8, %edx: length, rdi: correct */
+.Le_quad:
+	shll $3,%ecx
+	andl $7,%edx
+	addl %ecx,%edx
+	/* edx: bytes to zero, rdi: dest, eax:zero */
+.Lzero_rest:
+	movq %rdx,%rcx
+.Le_byte:
+	xorl %eax,%eax
+.Le5:	rep
+	stosb
+	/* when there is another exception while zeroing the rest just return */
+.Le_zero:
+	movq %rdx,%rax
+	jmp .Lende
+
+	/* Some CPUs run faster using the string copy instructions.
+	   This is also a lot simpler. Use them when possible.
+	   Patch in jmps to this code instead of copying it fully
+	   to avoid unwanted aliasing in the exception tables. */
+
+ /* rdi	destination
+  * rsi source
+  * rdx count
+  *
+  * Output:
+  * eax uncopied bytes or 0 if successfull.
+  *
+  * Only 4GB of copy is supported. This shouldn't be a problem
+  * because the kernel normally only writes from/to page sized chunks
+  * even if user space passed a longer buffer.
+  * And more would be dangerous because both Intel and AMD have
+  * errata with rep movsq > 4GB. If someone feels the need to fix
+  * this please consider this.
+   */
+copy_user_generic_c:
 	movl %edx,%ecx
 	shrl $3,%ecx
 	andl $7,%edx	
-	jz   5f
 1:	rep 
 	movsq 
 	movl %edx,%ecx
-	xor %eax,%eax
 2:	rep
 	movsb
-	ret
-	/* align here? */
-5: 	xorl %eax,%eax
-6:	rep movsq
-	ret
-
-	.section .fixup,"ax"
-3:	lea (%rdx,%rcx,8),%rax
-	ret
 4:	movl %ecx,%eax
 	ret
-	.previous
+3:	lea (%rdx,%rcx,8),%rax
+	ret
 
 	.section __ex_table,"a"
 	.quad 1b,3b
 	.quad 2b,4b
-	.quad 6b,4b
 	.previous
diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S
index 92dd805..5554948 100644
--- a/arch/x86_64/lib/memcpy.S
+++ b/arch/x86_64/lib/memcpy.S
@@ -11,8 +11,6 @@
  * 
  * Output:
  * rax original destination
- * 
- * TODO: check best memcpy for PSC
  */	
 
  	.globl __memcpy
@@ -20,6 +18,95 @@
 	.p2align 4
 __memcpy:
 memcpy:		
+	pushq %rbx
+	movq %rdi,%rax
+
+	movl %edx,%ecx
+	shrl $6,%ecx
+	jz .Lhandle_tail
+
+	.p2align 4
+.Lloop_64:
+	decl %ecx
+
+	movq (%rsi),%r11
+	movq 8(%rsi),%r8
+
+	movq %r11,(%rdi)
+	movq %r8,1*8(%rdi)
+
+	movq 2*8(%rsi),%r9
+	movq 3*8(%rsi),%r10
+
+	movq %r9,2*8(%rdi)
+	movq %r10,3*8(%rdi)
+
+	movq 4*8(%rsi),%r11
+	movq 5*8(%rsi),%r8
+
+	movq %r11,4*8(%rdi)
+	movq %r8,5*8(%rdi)
+
+	movq 6*8(%rsi),%r9
+	movq 7*8(%rsi),%r10
+
+	movq %r9,6*8(%rdi)
+	movq %r10,7*8(%rdi)
+
+	leaq 64(%rsi),%rsi
+	leaq 64(%rdi),%rdi
+	jnz  .Lloop_64
+
+.Lhandle_tail:
+	movl %edx,%ecx
+	andl $63,%ecx
+	shrl $3,%ecx
+	jz   .Lhandle_7
+	.p2align 4
+.Lloop_8:
+	decl %ecx
+	movq (%rsi),%r8
+	movq %r8,(%rdi)
+	leaq 8(%rdi),%rdi
+	leaq 8(%rsi),%rsi
+	jnz  .Lloop_8
+
+.Lhandle_7:
+	movl %edx,%ecx
+	andl $7,%ecx
+	jz .Lende
+	.p2align 4
+.Lloop_1:
+	movb (%rsi),%r8b
+	movb %r8b,(%rdi)
+	incq %rdi
+	incq %rsi
+	decl %ecx
+	jnz .Lloop_1
+
+.Lende:
+	popq %rbx
+	ret
+.Lfinal:
+
+	/* Some CPUs run faster using the string copy instructions.
+	   It is also a lot simpler. Use this when possible */
+
+	.section .altinstructions,"a"
+	.align 8
+	.quad  memcpy
+	.quad  memcpy_c
+	.byte  X86_FEATURE_REP_GOOD
+	.byte  .Lfinal-memcpy
+	.byte  memcpy_c_end-memcpy_c
+	.previous
+
+	.section .altinstr_replacement,"ax"
+ /* rdi	destination
+  * rsi source
+  * rdx count
+  */
+memcpy_c:
 	movq %rdi,%rax
 	movl %edx,%ecx
 	shrl $3,%ecx
@@ -30,3 +117,5 @@
 	rep
 	movsb
 	ret
+memcpy_c_end:
+	.previous
diff --git a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S
index 2aa48f2..ad397f2 100644
--- a/arch/x86_64/lib/memset.S
+++ b/arch/x86_64/lib/memset.S
@@ -13,6 +13,98 @@
 	.p2align 4
 memset:	
 __memset:
+	movq %rdi,%r10
+	movq %rdx,%r11
+
+	/* expand byte value  */
+	movzbl %sil,%ecx
+	movabs $0x0101010101010101,%rax
+	mul    %rcx		/* with rax, clobbers rdx */
+
+	/* align dst */
+	movl  %edi,%r9d
+	andl  $7,%r9d
+	jnz  .Lbad_alignment
+.Lafter_bad_alignment:
+
+	movl %r11d,%ecx
+	shrl $6,%ecx
+	jz	 .Lhandle_tail
+
+	.p2align 4
+.Lloop_64:
+	decl   %ecx
+	movq  %rax,(%rdi)
+	movq  %rax,8(%rdi)
+	movq  %rax,16(%rdi)
+	movq  %rax,24(%rdi)
+	movq  %rax,32(%rdi)
+	movq  %rax,40(%rdi)
+	movq  %rax,48(%rdi)
+	movq  %rax,56(%rdi)
+	leaq  64(%rdi),%rdi
+	jnz    .Lloop_64
+
+	/* Handle tail in loops. The loops should be faster than hard
+	   to predict jump tables. */
+	.p2align 4
+.Lhandle_tail:
+	movl	%r11d,%ecx
+	andl    $63&(~7),%ecx
+	jz 		.Lhandle_7
+	shrl	$3,%ecx
+	.p2align 4
+.Lloop_8:
+	decl   %ecx
+	movq  %rax,(%rdi)
+	leaq  8(%rdi),%rdi
+	jnz    .Lloop_8
+
+.Lhandle_7:
+	movl	%r11d,%ecx
+	andl	$7,%ecx
+	jz      .Lende
+	.p2align 4
+.Lloop_1:
+	decl    %ecx
+	movb 	%al,(%rdi)
+	leaq	1(%rdi),%rdi
+	jnz     .Lloop_1
+
+.Lende:
+	movq	%r10,%rax
+	ret
+
+.Lbad_alignment:
+	cmpq $7,%r11
+	jbe	.Lhandle_7
+	movq %rax,(%rdi)	/* unaligned store */
+	movq $8,%r8
+	subq %r9,%r8
+	addq %r8,%rdi
+	subq %r8,%r11
+	jmp .Lafter_bad_alignment
+
+	/* Some CPUs run faster using the string instructions.
+	   It is also a lot simpler. Use this when possible */
+
+#include <asm/cpufeature.h>
+
+	.section .altinstructions,"a"
+	.align 8
+	.quad  memset
+	.quad  memset_c
+	.byte  X86_FEATURE_REP_GOOD
+	.byte  memset_c_end-memset_c
+	.byte  memset_c_end-memset_c
+	.previous
+
+	.section .altinstr_replacement,"ax"
+ /* rdi	destination
+  * rsi value
+  * rdx count
+  */
+memset_c:
 	movq %rdi,%r9
 	movl %edx,%r8d
 	andl $7,%r8d		
@@ -29,3 +121,5 @@
 	stosb
 	movq %r9,%rax
 	ret
+memset_c_end:
+	.previous
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index 26eac19..2e7c3c8 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -33,7 +33,6 @@
 #include <asm/proto.h>
 #include <asm/kdebug.h>
 #include <asm-generic/sections.h>
-#include <asm/kdebug.h>
 
 /* Page fault error code bits */
 #define PF_PROT	(1<<0)		/* or no page found */
@@ -157,8 +156,8 @@
 
 	pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); 
 	pgd += pgd_index(address);
-	printk("PGD %lx ", pgd_val(*pgd));
 	if (bad_address(pgd)) goto bad;
+	printk("PGD %lx ", pgd_val(*pgd));
 	if (!pgd_present(*pgd)) goto ret; 
 
 	pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address);
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 8b7f856..cd25300 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -26,6 +26,10 @@
 static struct node nodes[MAX_NUMNODES] __initdata;
 static u8 pxm2node[256] = { [0 ... 255] = 0xff };
 
+/* Too small nodes confuse the VM badly. Usually they result
+   from BIOS bugs. */
+#define NODE_MIN_SIZE (4*1024*1024)
+
 static int node_to_pxm(int n);
 
 int pxm_to_node(int pxm)
@@ -131,7 +135,12 @@
 acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
 {
 	int pxm, node;
-	if (srat_disabled() || pa->flags.enabled == 0)
+	if (srat_disabled())
+		return;
+	if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) {		bad_srat();
+		return;
+	}
+	if (pa->flags.enabled == 0)
 		return;
 	pxm = pa->proximity_domain;
 	node = setup_node(pxm);
@@ -155,8 +164,16 @@
 	int node, pxm;
 	int i;
 
-	if (srat_disabled() || ma->flags.enabled == 0)
+	if (srat_disabled())
 		return;
+	if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) {
+		bad_srat();
+		return;
+	}
+	if (ma->flags.enabled == 0)
+		return;
+	start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
+	end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
 	pxm = ma->proximity_domain;
 	node = setup_node(pxm);
 	if (node < 0) {
@@ -164,8 +181,6 @@
 		bad_srat();
 		return;
 	}
-	start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
-	end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
 	/* It is fine to add this area to the nodes data it will be used later*/
 	if (ma->flags.hot_pluggable == 1)
 		printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n",
@@ -223,6 +238,16 @@
 	return 1;
 }
 
+static void unparse_node(int node)
+{
+	int i;
+	node_clear(node, nodes_parsed);
+	for (i = 0; i < MAX_LOCAL_APIC; i++) {
+		if (apicid_to_node[i] == node)
+			apicid_to_node[i] = NUMA_NO_NODE;
+	}
+}
+
 void __init acpi_numa_arch_fixup(void) {}
 
 /* Use the information discovered above to actually set up the nodes. */
@@ -230,16 +255,16 @@
 {
 	int i;
 
+	/* First clean up the node list */
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		cutoff_node(i, start, end);
+		if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE)
+			unparse_node(i);
+	}
+
 	if (acpi_numa <= 0)
 		return -1;
 
-	/* First clean up the node list */
-	for_each_node_mask(i, nodes_parsed) {
-		cutoff_node(i, start, end);
-		if (nodes[i].start == nodes[i].end)
-			node_clear(i, nodes_parsed);
-	}
-
 	if (!nodes_cover_memory()) {
 		bad_srat();
 		return -1;
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index 00d4ddb..18f371f 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -46,10 +46,10 @@
 	if (pci_mmcfg_config_num == 1 &&
 		cfg->pci_segment_group_number == 0 &&
 		(cfg->start_bus_number | cfg->end_bus_number) == 0)
-		return cfg->base_address;
+		return pci_mmcfg_virt[0].virt;
 
 	/* Fall back to type 0 */
-	return 0;
+	return NULL;
 }
 
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
diff --git a/block/elevator.c b/block/elevator.c
index 96a61e0..24b702d 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -293,7 +293,7 @@
 
 	rq->flags &= ~REQ_STARTED;
 
-	__elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE, 0);
+	elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
 }
 
 static void elv_drain_elevator(request_queue_t *q)
@@ -310,40 +310,11 @@
 	}
 }
 
-void __elv_add_request(request_queue_t *q, struct request *rq, int where,
-		       int plug)
+void elv_insert(request_queue_t *q, struct request *rq, int where)
 {
 	struct list_head *pos;
 	unsigned ordseq;
 
-	if (q->ordcolor)
-		rq->flags |= REQ_ORDERED_COLOR;
-
-	if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
-		/*
-		 * toggle ordered color
-		 */
-		q->ordcolor ^= 1;
-
-		/*
-		 * barriers implicitly indicate back insertion
-		 */
-		if (where == ELEVATOR_INSERT_SORT)
-			where = ELEVATOR_INSERT_BACK;
-
-		/*
-		 * this request is scheduling boundary, update end_sector
-		 */
-		if (blk_fs_request(rq)) {
-			q->end_sector = rq_end_sector(rq);
-			q->boundary_rq = rq;
-		}
-	} else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
-		where = ELEVATOR_INSERT_BACK;
-
-	if (plug)
-		blk_plug_device(q);
-
 	rq->q = q;
 
 	switch (where) {
@@ -424,6 +395,42 @@
 	}
 }
 
+void __elv_add_request(request_queue_t *q, struct request *rq, int where,
+		       int plug)
+{
+	if (q->ordcolor)
+		rq->flags |= REQ_ORDERED_COLOR;
+
+	if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
+		/*
+		 * toggle ordered color
+		 */
+		if (blk_barrier_rq(rq))
+			q->ordcolor ^= 1;
+
+		/*
+		 * barriers implicitly indicate back insertion
+		 */
+		if (where == ELEVATOR_INSERT_SORT)
+			where = ELEVATOR_INSERT_BACK;
+
+		/*
+		 * this request is scheduling boundary, update
+		 * end_sector
+		 */
+		if (blk_fs_request(rq)) {
+			q->end_sector = rq_end_sector(rq);
+			q->boundary_rq = rq;
+		}
+	} else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
+		where = ELEVATOR_INSERT_BACK;
+
+	if (plug)
+		blk_plug_device(q);
+
+	elv_insert(q, rq, where);
+}
+
 void elv_add_request(request_queue_t *q, struct request *rq, int where,
 		     int plug)
 {
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index f9fc07e..03d9c82 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -454,7 +454,7 @@
 	rq->end_io = end_io;
 	q->prepare_flush_fn(q, rq);
 
-	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+	elv_insert(q, rq, ELEVATOR_INSERT_FRONT);
 }
 
 static inline struct request *start_ordered(request_queue_t *q,
@@ -490,7 +490,7 @@
 	else
 		q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH;
 
-	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+	elv_insert(q, rq, ELEVATOR_INSERT_FRONT);
 
 	if (q->ordered & QUEUE_ORDERED_PREFLUSH) {
 		queue_flush(q, QUEUE_ORDERED_PREFLUSH);
@@ -508,7 +508,7 @@
 
 int blk_do_ordered(request_queue_t *q, struct request **rqp)
 {
-	struct request *rq = *rqp, *allowed_rq;
+	struct request *rq = *rqp;
 	int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
 
 	if (!q->ordseq) {
@@ -532,32 +532,26 @@
 		}
 	}
 
+	/*
+	 * Ordered sequence in progress
+	 */
+
+	/* Special requests are not subject to ordering rules. */
+	if (!blk_fs_request(rq) &&
+	    rq != &q->pre_flush_rq && rq != &q->post_flush_rq)
+		return 1;
+
 	if (q->ordered & QUEUE_ORDERED_TAG) {
+		/* Ordered by tag.  Blocking the next barrier is enough. */
 		if (is_barrier && rq != &q->bar_rq)
 			*rqp = NULL;
-		return 1;
+	} else {
+		/* Ordered by draining.  Wait for turn. */
+		WARN_ON(blk_ordered_req_seq(rq) < blk_ordered_cur_seq(q));
+		if (blk_ordered_req_seq(rq) > blk_ordered_cur_seq(q))
+			*rqp = NULL;
 	}
 
-	switch (blk_ordered_cur_seq(q)) {
-	case QUEUE_ORDSEQ_PREFLUSH:
-		allowed_rq = &q->pre_flush_rq;
-		break;
-	case QUEUE_ORDSEQ_BAR:
-		allowed_rq = &q->bar_rq;
-		break;
-	case QUEUE_ORDSEQ_POSTFLUSH:
-		allowed_rq = &q->post_flush_rq;
-		break;
-	default:
-		allowed_rq = NULL;
-		break;
-	}
-
-	if (rq != allowed_rq &&
-	    (blk_fs_request(rq) || rq == &q->pre_flush_rq ||
-	     rq == &q->post_flush_rq))
-		*rqp = NULL;
-
 	return 1;
 }
 
@@ -3453,7 +3447,7 @@
 	iocontext_cachep = kmem_cache_create("blkdev_ioc",
 			sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL);
 
-	for (i = 0; i < NR_CPUS; i++)
+	for_each_cpu(i)
 		INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i));
 
 	open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index cc72210..24f7af9 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -310,6 +310,8 @@
 	if (!rq->timeout)
 		rq->timeout = BLK_DEFAULT_TIMEOUT;
 
+	rq->retries = 0;
+
 	start_time = jiffies;
 
 	/* ignore return value. All information is passed back to caller
@@ -427,6 +429,7 @@
 	rq->data = buffer;
 	rq->data_len = bytes;
 	rq->flags |= REQ_BLOCK_PC;
+	rq->retries = 0;
 
 	blk_execute_rq(q, bd_disk, rq, 0);
 	err = rq->errors & 0xff;	/* only 8 bit SCSI status */
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 47ac90e..2953e2c 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -17,7 +17,6 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
-#include <asm/bug.h>
 #include <asm/scatterlist.h>
 #include "internal.h"
 #include "scatterwalk.h"
diff --git a/drivers/Makefile b/drivers/Makefile
index 619dd96..5c69b86 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -69,7 +69,7 @@
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
-obj-$(CONFIG_SGI_IOC4)		+= sn/
+obj-$(CONFIG_SGI_SN)		+= sn/
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
 obj-$(CONFIG_SUPERH)		+= sh/
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index be2dae5..eb730a8 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -94,7 +94,9 @@
 	return 0;
 }
 
-static struct dmi_system_id __initdata processor_power_dmi_table[] = {
+/* Actually this shouldn't be __cpuinitdata, would be better to fix the
+   callers to only run once -AK */
+static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
 	{ set_max_cstate, "IBM ThinkPad R40e", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
@@ -899,7 +901,7 @@
 		case ACPI_STATE_C3:
 			acpi_processor_power_verify_c3(pr, cx);
 #ifdef ARCH_APICTIMER_STOPS_ON_C3
-			if (c->x86_vendor == X86_VENDOR_INTEL) {
+			if (cx->valid && c->x86_vendor == X86_VENDOR_INTEL) {
 				on_each_cpu(switch_APIC_timer_to_ipi,
 						&mask, 1, 1);
 			}
diff --git a/drivers/base/base.h b/drivers/base/base.h
index e3b548d..5735b38 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -19,6 +19,10 @@
 extern void driver_detach(struct device_driver * drv);
 extern int driver_probe_device(struct device_driver *, struct device *);
 
+extern void sysdev_shutdown(void);
+extern int sysdev_suspend(pm_message_t state);
+extern int sysdev_resume(void);
+
 static inline struct class_device *to_class_dev(struct kobject *obj)
 {
 	return container_of(obj, struct class_device, kobj);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 29f6af5..c314156 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -133,6 +133,8 @@
 decl_subsys(bus, &ktype_bus, NULL);
 
 
+#ifdef CONFIG_HOTPLUG
+
 /* Manually detach a device from its associated driver. */
 static int driver_helper(struct device *dev, void *data)
 {
@@ -193,6 +195,7 @@
 }
 static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
 
+#endif
 
 static struct device * next_device(struct klist_iter * i)
 {
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index d1a0522..105a0d6 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -303,7 +303,7 @@
  */
 #ifdef CONFIG_ARCH_MEMORY_PROBE
 static ssize_t
-memory_probe_store(struct class *class, const char __user *buf, size_t count)
+memory_probe_store(struct class *class, const char *buf, size_t count)
 {
 	u64 phys_addr;
 	int ret;
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 0a7aa07..317edbf 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -9,10 +9,9 @@
  */
 
 #include <linux/device.h>
+#include "../base.h"
 #include "power.h"
 
-extern int sysdev_resume(void);
-
 
 /**
  *	resume_device - Restore state for one device.
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c
index c2475f3..8826a5b 100644
--- a/drivers/base/power/shutdown.c
+++ b/drivers/base/power/shutdown.c
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <asm/semaphore.h>
 
+#include "../base.h"
 #include "power.h"
 
 #define to_dev(node) container_of(node, struct device, kobj.entry)
@@ -28,7 +29,6 @@
  * they only get one called once when interrupts are disabled.
  */
 
-extern int sysdev_shutdown(void);
 
 /**
  * device_shutdown - call ->shutdown() on each device to shutdown.
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 5050176..8660779 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -9,10 +9,9 @@
  */
 
 #include <linux/device.h>
+#include "../base.h"
 #include "power.h"
 
-extern int sysdev_suspend(pm_message_t state);
-
 /*
  * The entries in the dpm_active list are in a depth first order, simply
  * because children are guaranteed to be discovered after parents, and
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index f3a0c56..40d7242 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -27,22 +27,30 @@
 
 static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
-	return sprintf(buf, "%u\n", dev->power.power_state.event);
+	if (dev->power.power_state.event)
+		return sprintf(buf, "2\n");
+	else
+		return sprintf(buf, "0\n");
 }
 
 static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
 {
 	pm_message_t state;
-	char * rest;
-	int error = 0;
+	int error = -EINVAL;
 
-	state.event = simple_strtoul(buf, &rest, 10);
-	if (*rest)
-		return -EINVAL;
-	if (state.event)
+	state.event = PM_EVENT_SUSPEND;
+	/* Older apps expected to write "3" here - confused with PCI D3 */
+	if ((n == 1) && !strcmp(buf, "3"))
 		error = dpm_runtime_suspend(dev, state);
-	else
+
+	if ((n == 1) && !strcmp(buf, "2"))
+		error = dpm_runtime_suspend(dev, state);
+
+	if ((n == 1) && !strcmp(buf, "0")) {
 		dpm_runtime_resume(dev);
+		error = 0;
+	}
+
 	return error ? error : n;
 }
 
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 66ed8f2..6fc23ab 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -21,8 +21,11 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <linux/device.h>
 #include <asm/semaphore.h>
 
+#include "base.h"
+
 extern struct subsystem devices_subsys;
 
 #define to_sysdev(k) container_of(k, struct sys_device, kobj)
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 139cbba..8b13316 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -433,12 +433,12 @@
 	  This controls the maximum number of active concurrent packets. More
 	  concurrent packets can increase write performance, but also require
 	  more memory. Each concurrent packet will require approximately 64Kb
-	  of non-swappable kernel memory, memory which will be allocated at
-	  pktsetup time.
+	  of non-swappable kernel memory, memory which will be allocated when
+	  a disc is opened for writing.
 
 config CDROM_PKTCDVD_WCACHE
-	bool "Enable write caching"
-	depends on CDROM_PKTCDVD
+	bool "Enable write caching (EXPERIMENTAL)"
+	depends on CDROM_PKTCDVD && EXPERIMENTAL
 	help
 	  If enabled, write caching will be set for the CD-R/W device. For now
 	  this option is dangerous unless the CD-RW media is known good, as we
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 12d7b9b..0d65394 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2183,6 +2183,7 @@
 {
 	CommandList_struct *cmd = rq->completion_data;
 	ctlr_info_t *h = hba[cmd->ctlr];
+	unsigned long flags;
 	u64bit temp64;
 	int i, ddir;
 
@@ -2205,10 +2206,10 @@
 	printk("Done with %p\n", rq);
 #endif /* CCISS_DEBUG */ 
 
-	spin_lock_irq(&h->lock);
+	spin_lock_irqsave(&h->lock, flags);
 	end_that_request_last(rq, rq->errors);
 	cmd_free(h, cmd,1);
-	spin_unlock_irq(&h->lock);
+	spin_unlock_irqrestore(&h->lock, flags);
 }
 
 /* checks the status of the job and calls complete buffers to mark all 
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 93affee..4e7dbcc 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -43,8 +43,6 @@
  *
  *************************************************************************/
 
-#define VERSION_CODE	"v0.2.0a 2004-07-14 Jens Axboe (axboe@suse.de) and petero2@telia.com"
-
 #include <linux/pktcdvd.h>
 #include <linux/config.h>
 #include <linux/module.h>
@@ -131,7 +129,7 @@
 /*
  * Allocate a packet_data struct
  */
-static struct packet_data *pkt_alloc_packet_data(void)
+static struct packet_data *pkt_alloc_packet_data(int frames)
 {
 	int i;
 	struct packet_data *pkt;
@@ -140,11 +138,12 @@
 	if (!pkt)
 		goto no_pkt;
 
-	pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE);
+	pkt->frames = frames;
+	pkt->w_bio = pkt_bio_alloc(frames);
 	if (!pkt->w_bio)
 		goto no_bio;
 
-	for (i = 0; i < PAGES_PER_PACKET; i++) {
+	for (i = 0; i < frames / FRAMES_PER_PAGE; i++) {
 		pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
 		if (!pkt->pages[i])
 			goto no_page;
@@ -152,7 +151,7 @@
 
 	spin_lock_init(&pkt->lock);
 
-	for (i = 0; i < PACKET_MAX_SIZE; i++) {
+	for (i = 0; i < frames; i++) {
 		struct bio *bio = pkt_bio_alloc(1);
 		if (!bio)
 			goto no_rd_bio;
@@ -162,14 +161,14 @@
 	return pkt;
 
 no_rd_bio:
-	for (i = 0; i < PACKET_MAX_SIZE; i++) {
+	for (i = 0; i < frames; i++) {
 		struct bio *bio = pkt->r_bios[i];
 		if (bio)
 			bio_put(bio);
 	}
 
 no_page:
-	for (i = 0; i < PAGES_PER_PACKET; i++)
+	for (i = 0; i < frames / FRAMES_PER_PAGE; i++)
 		if (pkt->pages[i])
 			__free_page(pkt->pages[i]);
 	bio_put(pkt->w_bio);
@@ -186,12 +185,12 @@
 {
 	int i;
 
-	for (i = 0; i < PACKET_MAX_SIZE; i++) {
+	for (i = 0; i < pkt->frames; i++) {
 		struct bio *bio = pkt->r_bios[i];
 		if (bio)
 			bio_put(bio);
 	}
-	for (i = 0; i < PAGES_PER_PACKET; i++)
+	for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++)
 		__free_page(pkt->pages[i]);
 	bio_put(pkt->w_bio);
 	kfree(pkt);
@@ -206,17 +205,17 @@
 	list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) {
 		pkt_free_packet_data(pkt);
 	}
+	INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
 }
 
 static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
 {
 	struct packet_data *pkt;
 
-	INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
-	INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
-	spin_lock_init(&pd->cdrw.active_list_lock);
+	BUG_ON(!list_empty(&pd->cdrw.pkt_free_list));
+
 	while (nr_packets > 0) {
-		pkt = pkt_alloc_packet_data();
+		pkt = pkt_alloc_packet_data(pd->settings.size >> 2);
 		if (!pkt) {
 			pkt_shrink_pktlist(pd);
 			return 0;
@@ -951,7 +950,7 @@
 
 	pd->current_sector = zone + pd->settings.size;
 	pkt->sector = zone;
-	pkt->frames = pd->settings.size >> 2;
+	BUG_ON(pkt->frames != pd->settings.size >> 2);
 	pkt->write_size = 0;
 
 	/*
@@ -1639,7 +1638,7 @@
 	pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2;
 	if (pd->settings.size == 0) {
 		printk("pktcdvd: detected zero packet size!\n");
-		pd->settings.size = 128;
+		return -ENXIO;
 	}
 	if (pd->settings.size > PACKET_MAX_SECTORS) {
 		printk("pktcdvd: packet size is too big\n");
@@ -1987,8 +1986,14 @@
 	if ((ret = pkt_set_segment_merging(pd, q)))
 		goto out_unclaim;
 
-	if (write)
+	if (write) {
+		if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
+			printk("pktcdvd: not enough memory for buffers\n");
+			ret = -ENOMEM;
+			goto out_unclaim;
+		}
 		printk("pktcdvd: %lukB available on disc\n", lba << 1);
+	}
 
 	return 0;
 
@@ -2014,6 +2019,8 @@
 	pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
 	bd_release(pd->bdev);
 	blkdev_put(pd->bdev);
+
+	pkt_shrink_pktlist(pd);
 }
 
 static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
@@ -2379,12 +2386,6 @@
 	/* This is safe, since we have a reference from open(). */
 	__module_get(THIS_MODULE);
 
-	if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
-		printk("pktcdvd: not enough memory for buffers\n");
-		ret = -ENOMEM;
-		goto out_mem;
-	}
-
 	pd->bdev = bdev;
 	set_blocksize(bdev, CD_FRAMESIZE);
 
@@ -2395,7 +2396,7 @@
 	if (IS_ERR(pd->cdrw.thread)) {
 		printk("pktcdvd: can't start kernel thread\n");
 		ret = -ENOMEM;
-		goto out_thread;
+		goto out_mem;
 	}
 
 	proc = create_proc_entry(pd->name, 0, pkt_proc);
@@ -2406,8 +2407,6 @@
 	DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
 	return 0;
 
-out_thread:
-	pkt_shrink_pktlist(pd);
 out_mem:
 	blkdev_put(bdev);
 	/* This is safe: open() is still holding a reference. */
@@ -2503,6 +2502,10 @@
 		goto out_mem;
 	pd->disk = disk;
 
+	INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
+	INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
+	spin_lock_init(&pd->cdrw.active_list_lock);
+
 	spin_lock_init(&pd->lock);
 	spin_lock_init(&pd->iosched.lock);
 	sprintf(pd->name, "pktcdvd%d", idx);
@@ -2567,8 +2570,6 @@
 
 	blkdev_put(pd->bdev);
 
-	pkt_shrink_pktlist(pd);
-
 	remove_proc_entry(pd->name, pkt_proc);
 	DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);
 
@@ -2678,7 +2679,6 @@
 
 	pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
 
-	DPRINTK("pktcdvd: %s\n", VERSION_CODE);
 	return 0;
 
 out:
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 193446e..e276172 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -42,8 +42,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
-#include <asm/bug.h>
-
 #include <asm/vio.h>
 #include <asm/scatterlist.h>
 #include <asm/iseries/hv_types.h>
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 4c67727..05ba410 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -222,7 +222,7 @@
 
 config SYNCLINK_GT
 	tristate "SyncLink GT/AC support"
-	depends on SERIAL_NONSTANDARD
+	depends on SERIAL_NONSTANDARD && PCI
 	help
 	  Support for SyncLink GT and SyncLink AC families of
 	  synchronous and asynchronous serial adapters
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 71b8b32..107df9f 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -980,7 +980,7 @@
 extern unsigned int drm_debug;
 extern unsigned int drm_cards_limit;
 extern drm_head_t **drm_heads;
-extern struct drm_sysfs_class *drm_class;
+extern struct class *drm_class;
 extern struct proc_dir_entry *drm_proc_root;
 
 				/* Proc support (drm_proc.h) */
@@ -1011,11 +1011,9 @@
 extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
 
 			       /* sysfs support (drm_sysfs.c) */
-struct drm_sysfs_class;
-extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
-						char *name);
-extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
-extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
+extern struct class *drm_sysfs_create(struct module *owner, char *name);
+extern void drm_sysfs_destroy(struct class *cs);
+extern struct class_device *drm_sysfs_device_add(struct class *cs,
 						 drm_head_t *head);
 extern void drm_sysfs_device_remove(struct class_device *class_dev);
 
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 7a9263f..68073e1 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -50,7 +50,7 @@
 module_param_named(debug, drm_debug, int, 0600);
 
 drm_head_t **drm_heads;
-struct drm_sysfs_class *drm_class;
+struct class *drm_class;
 struct proc_dir_entry *drm_proc_root;
 
 static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
index 68e43dd..0b9f98a 100644
--- a/drivers/char/drm/drm_sysfs.c
+++ b/drivers/char/drm/drm_sysfs.c
@@ -1,3 +1,4 @@
+
 /*
  * drm_sysfs.c - Modifications to drm_sysfs_class.c to support
  *               extra sysfs attribute from DRM. Normal drm_sysfs_class
@@ -19,36 +20,6 @@
 #include "drm_core.h"
 #include "drmP.h"
 
-struct drm_sysfs_class {
-	struct class_device_attribute attr;
-	struct class class;
-};
-#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
-
-struct simple_dev {
-	dev_t dev;
-	struct class_device class_dev;
-};
-#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
-
-static void release_simple_dev(struct class_device *class_dev)
-{
-	struct simple_dev *s_dev = to_simple_dev(class_dev);
-	kfree(s_dev);
-}
-
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
-	struct simple_dev *s_dev = to_simple_dev(class_dev);
-	return print_dev_t(buf, s_dev->dev);
-}
-
-static void drm_sysfs_class_release(struct class *class)
-{
-	struct drm_sysfs_class *cs = to_drm_sysfs_class(class);
-	kfree(cs);
-}
-
 /* Display the version of drm_core. This doesn't work right in current design */
 static ssize_t version_show(struct class *dev, char *buf)
 {
@@ -69,38 +40,16 @@
  * Note, the pointer created here is to be destroyed when finished by making a
  * call to drm_sysfs_destroy().
  */
-struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
+struct class *drm_sysfs_create(struct module *owner, char *name)
 {
-	struct drm_sysfs_class *cs;
-	int retval;
+	struct class *class;
 
-	cs = kmalloc(sizeof(*cs), GFP_KERNEL);
-	if (!cs) {
-		retval = -ENOMEM;
-		goto error;
-	}
-	memset(cs, 0x00, sizeof(*cs));
+	class = class_create(owner, name);
+	if (!class)
+		return class;
 
-	cs->class.name = name;
-	cs->class.class_release = drm_sysfs_class_release;
-	cs->class.release = release_simple_dev;
-
-	cs->attr.attr.name = "dev";
-	cs->attr.attr.mode = S_IRUGO;
-	cs->attr.attr.owner = owner;
-	cs->attr.show = show_dev;
-	cs->attr.store = NULL;
-
-	retval = class_register(&cs->class);
-	if (retval)
-		goto error;
-	class_create_file(&cs->class, &class_attr_version);
-
-	return cs;
-
-      error:
-	kfree(cs);
-	return ERR_PTR(retval);
+	class_create_file(class, &class_attr_version);
+	return class;
 }
 
 /**
@@ -110,12 +59,13 @@
  * Note, the pointer to be destroyed must have been created with a call to
  * drm_sysfs_create().
  */
-void drm_sysfs_destroy(struct drm_sysfs_class *cs)
+void drm_sysfs_destroy(struct class *class)
 {
-	if ((cs == NULL) || (IS_ERR(cs)))
+	if ((class == NULL) || (IS_ERR(class)))
 		return;
 
-	class_unregister(&cs->class);
+	class_remove_file(class, &class_attr_version);
+	class_destroy(class);
 }
 
 static ssize_t show_dri(struct class_device *class_device, char *buf)
@@ -132,7 +82,7 @@
 
 /**
  * drm_sysfs_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
+ * @cs: pointer to the struct class that this device should be registered to.
  * @dev: the dev_t for the device to be added.
  * @device: a pointer to a struct device that is assiociated with this class device.
  * @fmt: string for the class device's name
@@ -141,46 +91,26 @@
  * class.  A "dev" file will be created, showing the dev_t for the device.  The
  * pointer to the struct class_device will be returned from the call.  Any further
  * sysfs files that might be required can be created using this pointer.
- * Note: the struct drm_sysfs_class passed to this function must have previously been
+ * Note: the struct class passed to this function must have previously been
  * created with a call to drm_sysfs_create().
  */
-struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
-					  drm_head_t *head)
+struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
 {
-	struct simple_dev *s_dev = NULL;
-	int i, retval;
+	struct class_device *class_dev;
+	int i;
 
-	if ((cs == NULL) || (IS_ERR(cs))) {
-		retval = -ENODEV;
-		goto error;
-	}
+	class_dev = class_device_create(cs, NULL,
+					MKDEV(DRM_MAJOR, head->minor),
+					&(head->dev->pdev)->dev,
+					"card%d", head->minor);
+	if (!class_dev)
+		return NULL;
 
-	s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
-	if (!s_dev) {
-		retval = -ENOMEM;
-		goto error;
-	}
-	memset(s_dev, 0x00, sizeof(*s_dev));
-
-	s_dev->dev = MKDEV(DRM_MAJOR, head->minor);
-	s_dev->class_dev.dev = &(head->dev->pdev)->dev;
-	s_dev->class_dev.class = &cs->class;
-
-	snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor);
-	retval = class_device_register(&s_dev->class_dev);
-	if (retval)
-		goto error;
-
-	class_device_create_file(&s_dev->class_dev, &cs->attr);
-	class_set_devdata(&s_dev->class_dev, head);
+	class_set_devdata(class_dev, head);
 
 	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
-	return &s_dev->class_dev;
-
-error:
-	kfree(s_dev);
-	return ERR_PTR(retval);
+		class_device_create_file(class_dev, &class_device_attrs[i]);
+	return class_dev;
 }
 
 /**
@@ -192,10 +122,9 @@
  */
 void drm_sysfs_device_remove(struct class_device *class_dev)
 {
-	struct simple_dev *s_dev = to_simple_dev(class_dev);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-		class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]);
-	class_device_unregister(&s_dev->class_dev);
+		class_device_remove_file(class_dev, &class_device_attrs[i]);
+	class_device_unregister(class_dev);
 }
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 80a5b84..fee68cc 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -103,6 +103,7 @@
 
 #include <linux/serial.h>
 #include <linux/generic_serial.h>
+#include <linux/tty_flip.h>
 
 #include "ser_a2232.h"
 #include "ser_a2232fw.h"
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
index 7a4dfb9..837b1ec3 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -92,7 +92,7 @@
 	return 0;
 }
 
-static ssize_t epx_c3_write(struct file *file, const char *data,
+static ssize_t epx_c3_write(struct file *file, const char __user *data,
 			size_t len, loff_t *ppos)
 {
 	/* Refresh the timer. */
@@ -105,6 +105,7 @@
 			unsigned int cmd, unsigned long arg)
 {
 	int options, retval = -EINVAL;
+	int __user *argp = (void __user *)arg;
 	static struct watchdog_info ident = {
 		.options		= WDIOF_KEEPALIVEPING |
 					  WDIOF_MAGICCLOSE,
@@ -114,20 +115,19 @@
 
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		if (copy_to_user((struct watchdog_info *)arg,
-				 &ident, sizeof(ident)))
+		if (copy_to_user(argp, &ident, sizeof(ident)))
 			return -EFAULT;
 		return 0;
 	case WDIOC_GETSTATUS:
 	case WDIOC_GETBOOTSTATUS:
-		return put_user(0,(int *)arg);
+		return put_user(0, argp);
 	case WDIOC_KEEPALIVE:
 		epx_c3_pet();
 		return 0;
 	case WDIOC_GETTIMEOUT:
-		return put_user(WATCHDOG_TIMEOUT,(int *)arg);
-	case WDIOC_SETOPTIONS: {
-		if (get_user(options, (int *)arg))
+		return put_user(WATCHDOG_TIMEOUT, argp);
+	case WDIOC_SETOPTIONS:
+		if (get_user(options, argp))
 			return -EFAULT;
 
 		if (options & WDIOS_DISABLECARD) {
@@ -141,7 +141,6 @@
 		}
 
 		return retval;
-	}
 	default:
 		return -ENOIOCTLCMD;
 	}
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index d94331c..18a4556 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -11,7 +11,6 @@
 config EDAC
 	tristate "EDAC core system error reporting"
 	depends on X86
-	default y
 	help
 	  EDAC is designed to report errors in the core system.
 	  These are low-level errors that are reported in the CPU or
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
index 009c08f..1991f94 100644
--- a/drivers/edac/i82875p_edac.c
+++ b/drivers/edac/i82875p_edac.c
@@ -159,7 +159,7 @@
 
 struct i82875p_pvt {
 	struct pci_dev *ovrfl_pdev;
-	void *ovrfl_window;
+	void __iomem *ovrfl_window;
 };
 
 
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c582959..7230d4e 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -113,6 +113,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called ds1621.
 
+config SENSORS_F71805F
+	tristate "Fintek F71805F/FG"
+	depends on HWMON && EXPERIMENTAL
+	help
+	  If you say yes here you get support for hardware monitoring
+	  features of the Fintek F71805F/FG chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called f71805f.
+
 config SENSORS_FSCHER
 	tristate "FSC Hermes"
 	depends on HWMON && I2C && EXPERIMENTAL
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 06d4a1d..fbdb8d9 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -18,6 +18,7 @@
 obj-$(CONFIG_SENSORS_ADM9240)	+= adm9240.o
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_DS1621)	+= ds1621.o
+obj-$(CONFIG_SENSORS_F71805F)	+= f71805f.o
 obj-$(CONFIG_SENSORS_FSCHER)	+= fscher.o
 obj-$(CONFIG_SENSORS_FSCPOS)	+= fscpos.o
 obj-$(CONFIG_SENSORS_GL518SM)	+= gl518sm.o
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
new file mode 100644
index 0000000..e029e0a
--- /dev/null
+++ b/drivers/hwmon/f71805f.c
@@ -0,0 +1,908 @@
+/*
+ * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated
+ *             hardware monitoring features
+ * Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+ *
+ * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
+ * complete hardware monitoring features: voltage, fan and temperature
+ * sensors, and manual and automatic fan speed control.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <asm/io.h>
+
+static struct platform_device *pdev;
+
+#define DRVNAME "f71805f"
+
+/*
+ * Super-I/O constants and functions
+ */
+
+#define F71805F_LD_HWM		0x04
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_DEVREV		0x22	/* Device revision */
+#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID		0x1934
+#define SIO_F71805F_ID		0x0406
+
+static inline int
+superio_inb(int base, int reg)
+{
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static int
+superio_inw(int base, int reg)
+{
+	int val;
+	outb(reg++, base);
+	val = inb(base + 1) << 8;
+	outb(reg, base);
+	val |= inb(base + 1);
+	return val;
+}
+
+static inline void
+superio_select(int base, int ld)
+{
+	outb(SIO_REG_LDSEL, base);
+	outb(ld, base + 1);
+}
+
+static inline void
+superio_enter(int base)
+{
+	outb(0x87, base);
+	outb(0x87, base);
+}
+
+static inline void
+superio_exit(int base)
+{
+	outb(0xaa, base);
+}
+
+/*
+ * ISA constants
+ */
+
+#define REGION_LENGTH		2
+#define ADDR_REG_OFFSET		0
+#define DATA_REG_OFFSET		1
+
+static struct resource f71805f_resource __initdata = {
+	.flags	= IORESOURCE_IO,
+};
+
+/*
+ * Registers
+ */
+
+/* in nr from 0 to 8 (8-bit values) */
+#define F71805F_REG_IN(nr)		(0x10 + (nr))
+#define F71805F_REG_IN_HIGH(nr)		(0x40 + 2 * (nr))
+#define F71805F_REG_IN_LOW(nr)		(0x41 + 2 * (nr))
+/* fan nr from 0 to 2 (12-bit values, two registers) */
+#define F71805F_REG_FAN(nr)		(0x20 + 2 * (nr))
+#define F71805F_REG_FAN_LOW(nr)		(0x28 + 2 * (nr))
+#define F71805F_REG_FAN_CTRL(nr)	(0x60 + 16 * (nr))
+/* temp nr from 0 to 2 (8-bit values) */
+#define F71805F_REG_TEMP(nr)		(0x1B + (nr))
+#define F71805F_REG_TEMP_HIGH(nr)	(0x54 + 2 * (nr))
+#define F71805F_REG_TEMP_HYST(nr)	(0x55 + 2 * (nr))
+#define F71805F_REG_TEMP_MODE		0x01
+
+#define F71805F_REG_START		0x00
+/* status nr from 0 to 2 */
+#define F71805F_REG_STATUS(nr)		(0x36 + (nr))
+
+/*
+ * Data structures and manipulation thereof
+ */
+
+struct f71805f_data {
+	unsigned short addr;
+	const char *name;
+	struct semaphore lock;
+	struct class_device *class_dev;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+	unsigned long last_limits;	/* In jiffies */
+
+	/* Register values */
+	u8 in[9];
+	u8 in_high[9];
+	u8 in_low[9];
+	u16 fan[3];
+	u16 fan_low[3];
+	u8 fan_enabled;		/* Read once at init time */
+	u8 temp[3];
+	u8 temp_high[3];
+	u8 temp_hyst[3];
+	u8 temp_mode;
+	u8 alarms[3];
+};
+
+static inline long in_from_reg(u8 reg)
+{
+	return (reg * 8);
+}
+
+/* The 2 least significant bits are not used */
+static inline u8 in_to_reg(long val)
+{
+	if (val <= 0)
+		return 0;
+	if (val >= 2016)
+		return 0xfc;
+	return (((val + 16) / 32) << 2);
+}
+
+/* in0 is downscaled by a factor 2 internally */
+static inline long in0_from_reg(u8 reg)
+{
+	return (reg * 16);
+}
+
+static inline u8 in0_to_reg(long val)
+{
+	if (val <= 0)
+		return 0;
+	if (val >= 4032)
+		return 0xfc;
+	return (((val + 32) / 64) << 2);
+}
+
+/* The 4 most significant bits are not used */
+static inline long fan_from_reg(u16 reg)
+{
+	reg &= 0xfff;
+	if (!reg || reg == 0xfff)
+		return 0;
+	return (1500000 / reg);
+}
+
+static inline u16 fan_to_reg(long rpm)
+{
+	/* If the low limit is set below what the chip can measure,
+	   store the largest possible 12-bit value in the registers,
+	   so that no alarm will ever trigger. */
+	if (rpm < 367)
+		return 0xfff;
+	return (1500000 / rpm);
+}
+
+static inline long temp_from_reg(u8 reg)
+{
+	return (reg * 1000);
+}
+
+static inline u8 temp_to_reg(long val)
+{
+	if (val < 0)
+		val = 0;
+	else if (val > 1000 * 0xff)
+		val = 0xff;
+	return ((val + 500) / 1000);
+}
+
+/*
+ * Device I/O access
+ */
+
+static u8 f71805f_read8(struct f71805f_data *data, u8 reg)
+{
+	u8 val;
+
+	down(&data->lock);
+	outb(reg, data->addr + ADDR_REG_OFFSET);
+	val = inb(data->addr + DATA_REG_OFFSET);
+	up(&data->lock);
+
+	return val;
+}
+
+static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
+{
+	down(&data->lock);
+	outb(reg, data->addr + ADDR_REG_OFFSET);
+	outb(val, data->addr + DATA_REG_OFFSET);
+	up(&data->lock);
+}
+
+/* It is important to read the MSB first, because doing so latches the
+   value of the LSB, so we are sure both bytes belong to the same value. */
+static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
+{
+	u16 val;
+
+	down(&data->lock);
+	outb(reg, data->addr + ADDR_REG_OFFSET);
+	val = inb(data->addr + DATA_REG_OFFSET) << 8;
+	outb(++reg, data->addr + ADDR_REG_OFFSET);
+	val |= inb(data->addr + DATA_REG_OFFSET);
+	up(&data->lock);
+
+	return val;
+}
+
+static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
+{
+	down(&data->lock);
+	outb(reg, data->addr + ADDR_REG_OFFSET);
+	outb(val >> 8, data->addr + DATA_REG_OFFSET);
+	outb(++reg, data->addr + ADDR_REG_OFFSET);
+	outb(val & 0xff, data->addr + DATA_REG_OFFSET);
+	up(&data->lock);
+}
+
+static struct f71805f_data *f71805f_update_device(struct device *dev)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	int nr;
+
+	down(&data->update_lock);
+
+	/* Limit registers cache is refreshed after 60 seconds */
+	if (time_after(jiffies, data->last_updated + 60 * HZ)
+	 || !data->valid) {
+		for (nr = 0; nr < 9; nr++) {
+			data->in_high[nr] = f71805f_read8(data,
+					    F71805F_REG_IN_HIGH(nr));
+			data->in_low[nr] = f71805f_read8(data,
+					   F71805F_REG_IN_LOW(nr));
+		}
+		for (nr = 0; nr < 3; nr++) {
+			if (data->fan_enabled & (1 << nr))
+				data->fan_low[nr] = f71805f_read16(data,
+						    F71805F_REG_FAN_LOW(nr));
+		}
+		for (nr = 0; nr < 3; nr++) {
+			data->temp_high[nr] = f71805f_read8(data,
+					      F71805F_REG_TEMP_HIGH(nr));
+			data->temp_hyst[nr] = f71805f_read8(data,
+					      F71805F_REG_TEMP_HYST(nr));
+		}
+		data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE);
+
+		data->last_limits = jiffies;
+	}
+
+	/* Measurement registers cache is refreshed after 1 second */
+	if (time_after(jiffies, data->last_updated + HZ)
+	 || !data->valid) {
+		for (nr = 0; nr < 9; nr++) {
+			data->in[nr] = f71805f_read8(data,
+				       F71805F_REG_IN(nr));
+		}
+		for (nr = 0; nr < 3; nr++) {
+			if (data->fan_enabled & (1 << nr))
+				data->fan[nr] = f71805f_read16(data,
+						F71805F_REG_FAN(nr));
+		}
+		for (nr = 0; nr < 3; nr++) {
+			data->temp[nr] = f71805f_read8(data,
+					 F71805F_REG_TEMP(nr));
+		}
+		for (nr = 0; nr < 3; nr++) {
+			data->alarms[nr] = f71805f_read8(data,
+					   F71805F_REG_STATUS(nr));
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+/*
+ * Sysfs interface
+ */
+
+static ssize_t show_in0(struct device *dev, struct device_attribute *devattr,
+			char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+
+	return sprintf(buf, "%ld\n", in0_from_reg(data->in[0]));
+}
+
+static ssize_t show_in0_max(struct device *dev, struct device_attribute
+			    *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+
+	return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0]));
+}
+
+static ssize_t show_in0_min(struct device *dev, struct device_attribute
+			    *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+
+	return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0]));
+}
+
+static ssize_t set_in0_max(struct device *dev, struct device_attribute
+			   *devattr, const char *buf, size_t count)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_high[0] = in0_to_reg(val);
+	f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t set_in0_min(struct device *dev, struct device_attribute
+			   *devattr, const char *buf, size_t count)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_low[0] = in0_to_reg(val);
+	f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL);
+static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max);
+static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min);
+
+static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
+		       char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", in_from_reg(data->in[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev, struct device_attribute
+			   *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev, struct device_attribute
+			   *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr]));
+}
+
+static ssize_t set_in_max(struct device *dev, struct device_attribute
+			  *devattr, const char *buf, size_t count)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_high[nr] = in_to_reg(val);
+	f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute
+			  *devattr, const char *buf, size_t count)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_low[nr] = in_to_reg(val);
+	f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define sysfs_in(offset)					\
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,		\
+		show_in, NULL, offset);				\
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_in_max, set_in_max, offset);		\
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_in_min, set_in_min, offset)
+
+sysfs_in(1);
+sysfs_in(2);
+sysfs_in(3);
+sysfs_in(4);
+sysfs_in(5);
+sysfs_in(6);
+sysfs_in(7);
+sysfs_in(8);
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
+			char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr]));
+}
+
+static ssize_t show_fan_min(struct device *dev, struct device_attribute
+			    *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr]));
+}
+
+static ssize_t set_fan_min(struct device *dev, struct device_attribute
+			   *devattr, const char *buf, size_t count)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_low[nr] = fan_to_reg(val);
+	f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define sysfs_fan(offset)					\
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,		\
+		show_fan, NULL, offset - 1);			\
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_fan_min, set_fan_min, offset - 1)
+
+sysfs_fan(1);
+sysfs_fan(2);
+sysfs_fan(3);
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
+			 char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr]));
+}
+
+static ssize_t show_temp_max(struct device *dev, struct device_attribute
+			     *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr]));
+}
+
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr]));
+}
+
+static ssize_t show_temp_type(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+
+	/* 3 is diode, 4 is thermistor */
+	return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4);
+}
+
+static ssize_t set_temp_max(struct device *dev, struct device_attribute
+			    *devattr, const char *buf, size_t count)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_high[nr] = temp_to_reg(val);
+	f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute
+			     *devattr, const char *buf, size_t count)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	int nr = attr->index;
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_hyst[nr] = temp_to_reg(val);
+	f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define sysfs_temp(offset)						\
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
+		show_temp, NULL, offset - 1);				\
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_temp_max, set_temp_max, offset - 1);		\
+static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR,	\
+		show_temp_hyst, set_temp_hyst, offset - 1);		\
+static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO,			\
+		show_temp_type, NULL, offset - 1)
+
+sysfs_temp(1);
+sysfs_temp(2);
+sysfs_temp(3);
+
+static ssize_t show_alarms_in(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+
+	return sprintf(buf, "%d\n", data->alarms[0] |
+				    ((data->alarms[1] & 0x01) << 8));
+}
+
+static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
+			       *devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+
+	return sprintf(buf, "%d\n", data->alarms[2] & 0x07);
+}
+
+static ssize_t show_alarms_temp(struct device *dev, struct device_attribute
+				*devattr, char *buf)
+{
+	struct f71805f_data *data = f71805f_update_device(dev);
+
+	return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07);
+}
+
+static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL);
+static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL);
+static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL);
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+			 *devattr, char *buf)
+{
+	struct f71805f_data *data = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", data->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+/*
+ * Device registration and initialization
+ */
+
+static void __devinit f71805f_init_device(struct f71805f_data *data)
+{
+	u8 reg;
+	int i;
+
+	reg = f71805f_read8(data, F71805F_REG_START);
+	if ((reg & 0x41) != 0x01) {
+		printk(KERN_DEBUG DRVNAME ": Starting monitoring "
+		       "operations\n");
+		f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40);
+	}
+
+	/* Fan monitoring can be disabled. If it is, we won't be polling
+	   the register values, and won't create the related sysfs files. */
+	for (i = 0; i < 3; i++) {
+		reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i));
+		if (!(reg & 0x80))
+			data->fan_enabled |= (1 << i);
+	}
+}
+
+static int __devinit f71805f_probe(struct platform_device *pdev)
+{
+	struct f71805f_data *data;
+	struct resource *res;
+	int err;
+
+	if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		printk(KERN_ERR DRVNAME ": Out of memory\n");
+		goto exit;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	data->addr = res->start;
+	init_MUTEX(&data->lock);
+	data->name = "f71805f";
+	init_MUTEX(&data->update_lock);
+
+	platform_set_drvdata(pdev, data);
+
+	data->class_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(data->class_dev)) {
+		err = PTR_ERR(data->class_dev);
+		dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+		goto exit_free;
+	}
+
+	/* Initialize the F71805F chip */
+	f71805f_init_device(data);
+
+	/* Register sysfs interface files */
+	device_create_file(&pdev->dev, &dev_attr_in0_input);
+	device_create_file(&pdev->dev, &dev_attr_in0_max);
+	device_create_file(&pdev->dev, &dev_attr_in0_min);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr);
+	if (data->fan_enabled & (1 << 0)) {
+		device_create_file(&pdev->dev,
+				   &sensor_dev_attr_fan1_input.dev_attr);
+		device_create_file(&pdev->dev,
+				   &sensor_dev_attr_fan1_min.dev_attr);
+	}
+	if (data->fan_enabled & (1 << 1)) {
+		device_create_file(&pdev->dev,
+				   &sensor_dev_attr_fan2_input.dev_attr);
+		device_create_file(&pdev->dev,
+				   &sensor_dev_attr_fan2_min.dev_attr);
+	}
+	if (data->fan_enabled & (1 << 2)) {
+		device_create_file(&pdev->dev,
+				   &sensor_dev_attr_fan3_input.dev_attr);
+		device_create_file(&pdev->dev,
+				   &sensor_dev_attr_fan3_min.dev_attr);
+	}
+	device_create_file(&pdev->dev,
+			   &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&pdev->dev,
+			   &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&pdev->dev,
+			   &sensor_dev_attr_temp3_input.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr);
+	device_create_file(&pdev->dev,
+			   &sensor_dev_attr_temp1_max_hyst.dev_attr);
+	device_create_file(&pdev->dev,
+			   &sensor_dev_attr_temp2_max_hyst.dev_attr);
+	device_create_file(&pdev->dev,
+			   &sensor_dev_attr_temp3_max_hyst.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr);
+	device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr);
+	device_create_file(&pdev->dev, &dev_attr_alarms_in);
+	device_create_file(&pdev->dev, &dev_attr_alarms_fan);
+	device_create_file(&pdev->dev, &dev_attr_alarms_temp);
+	device_create_file(&pdev->dev, &dev_attr_name);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int __devexit f71805f_remove(struct platform_device *pdev)
+{
+	struct f71805f_data *data = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	hwmon_device_unregister(data->class_dev);
+	kfree(data);
+
+	return 0;
+}
+
+static struct platform_driver f71805f_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= DRVNAME,
+	},
+	.probe		= f71805f_probe,
+	.remove		= __devexit_p(f71805f_remove),
+};
+
+static int __init f71805f_device_add(unsigned short address)
+{
+	int err;
+
+	pdev = platform_device_alloc(DRVNAME, address);
+	if (!pdev) {
+		err = -ENOMEM;
+		printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+		goto exit;
+	}
+
+	f71805f_resource.start = address;
+	f71805f_resource.end = address + REGION_LENGTH - 1;
+	f71805f_resource.name = pdev->name;
+	err = platform_device_add_resources(pdev, &f71805f_resource, 1);
+	if (err) {
+		printk(KERN_ERR DRVNAME ": Device resource addition failed "
+		       "(%d)\n", err);
+		goto exit_device_put;
+	}
+
+	err = platform_device_add(pdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+		       err);
+		goto exit_device_put;
+	}
+
+	return 0;
+
+exit_device_put:
+	platform_device_put(pdev);
+exit:
+	return err;
+}
+
+static int __init f71805f_find(int sioaddr, unsigned short *address)
+{
+	int err = -ENODEV;
+	u16 devid;
+
+	superio_enter(sioaddr);
+
+	devid = superio_inw(sioaddr, SIO_REG_MANID);
+	if (devid != SIO_FINTEK_ID)
+		goto exit;
+
+	devid = superio_inw(sioaddr, SIO_REG_DEVID);
+	if (devid != SIO_F71805F_ID) {
+		printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
+		       "skipping\n");
+		goto exit;
+	}
+
+	superio_select(sioaddr, F71805F_LD_HWM);
+	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
+		printk(KERN_WARNING DRVNAME ": Device not activated, "
+		       "skipping\n");
+		goto exit;
+	}
+
+	*address = superio_inw(sioaddr, SIO_REG_ADDR);
+	if (*address == 0) {
+		printk(KERN_WARNING DRVNAME ": Base address not set, "
+		       "skipping\n");
+		goto exit;
+	}
+
+	err = 0;
+	printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n",
+	       *address, superio_inb(sioaddr, SIO_REG_DEVREV));
+
+exit:
+	superio_exit(sioaddr);
+	return err;
+}
+
+static int __init f71805f_init(void)
+{
+	int err;
+	unsigned short address;
+
+	if (f71805f_find(0x2e, &address)
+	 && f71805f_find(0x4e, &address))
+		return -ENODEV;
+
+	err = platform_driver_register(&f71805f_driver);
+	if (err)
+		goto exit;
+
+	/* Sets global pdev as a side effect */
+	err = f71805f_device_add(address);
+	if (err)
+		goto exit_driver;
+
+	return 0;
+
+exit_driver:
+	platform_driver_unregister(&f71805f_driver);
+exit:
+	return err;
+}
+
+static void __exit f71805f_exit(void)
+{
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&f71805f_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("F71805F hardware monitoring driver");
+
+module_init(f71805f_init);
+module_exit(f71805f_exit);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 0da7c9c..e87d52c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -45,8 +45,7 @@
 
 
 /* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
-					0x2e, 0x2f, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
 static unsigned short isa_address;
 
 /* Insmod parameters */
@@ -830,6 +829,11 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto ERROR2;
 
+	if (!is_isa)
+		dev_info(&new_client->dev, "The I2C interface to IT87xxF "
+			 "hardware monitoring chips is deprecated. Please "
+			 "report if you still rely on it.\n");
+
 	/* Check PWM configuration */
 	enable_pwm_interface = it87_check_pwm(new_client);
 
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index a2f420d..df9e02a 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -87,15 +87,15 @@
 
 /* In the temperature registers, the low 3 bits are not part of the
    temperature values; they are the status bits. */
-static inline u16 LM77_TEMP_TO_REG(int temp)
+static inline s16 LM77_TEMP_TO_REG(int temp)
 {
 	int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
-	return (u16)((ntemp / 500) * 8);
+	return (ntemp / 500) * 8;
 }
 
-static inline int LM77_TEMP_FROM_REG(u16 reg)
+static inline int LM77_TEMP_FROM_REG(s16 reg)
 {
-	return ((int)reg / 8) * 500;
+	return (reg / 8) * 500;
 }
 
 /* sysfs stuff */
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index b176bf0..a2f6bb6 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -303,10 +303,6 @@
 static int w83792d_attach_adapter(struct i2c_adapter *adapter);
 static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind);
 static int w83792d_detach_client(struct i2c_client *client);
-
-static int w83792d_read_value(struct i2c_client *client, u8 register);
-static int w83792d_write_value(struct i2c_client *client, u8 register,
-				u8 value);
 static struct w83792d_data *w83792d_update_device(struct device *dev);
 
 #ifdef DEBUG
@@ -329,6 +325,20 @@
 	return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03));
 }
 
+/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
+   but the driver only accesses registers in bank 0, so we don't have
+   to switch banks and lock access between switches. */
+static inline int w83792d_read_value(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static inline int
+w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
 /* following are the sysfs callback functions */
 static ssize_t show_in(struct device *dev, struct device_attribute *attr,
 			char *buf)
@@ -1386,19 +1396,6 @@
 	return 0;
 }
 
-/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
-   but the driver only accesses registers in bank 0, so we don't have
-   to switch banks and lock access between switches. */
-static int w83792d_read_value(struct i2c_client *client, u8 reg)
-{
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
 static void
 w83792d_init_client(struct i2c_client *client)
 {
diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c
index 938848a..3df3f09 100644
--- a/drivers/i2c/algos/i2c-algo-sibyte.c
+++ b/drivers/i2c/algos/i2c-algo-sibyte.c
@@ -202,7 +202,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
 MODULE_DESCRIPTION("SiByte I2C-Bus algorithm");
-MODULE_PARM(bit_scan, "i");
+module_param(bit_scan, int, 0);
 MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 08d5b8f..ff92735 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -124,6 +124,7 @@
 	    ICH6
 	    ICH7
 	    ESB2
+	    ICH8
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 1c752dd..8e0f315 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -32,6 +32,7 @@
     ICH6		266A
     ICH7		27DA
     ESB2		269B
+    ICH8		283E
     This driver supports several versions of Intel's I/O Controller Hubs (ICH).
     For SMBus support, they are similar to the PIIX4 and are part
     of Intel's '810' and other chipsets.
@@ -527,6 +528,7 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
 	{ 0, }
 };
 
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
index 3e5eba9..c63025a 100644
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -121,14 +121,11 @@
 
 static int __init i2c_parport_init(void)
 {
-	int type_count;
-
-	type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm);
-	if (type < 0 || type >= type_count) {
+	if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
 		printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
 		type = 0;
 	}
-	
+
 	if (base == 0) {
 		printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE);
 		base = DEFAULT_BASE;
@@ -152,7 +149,7 @@
 		release_region(base, 3);
 		return -ENODEV;
 	}
-	
+
 	return 0;
 }
 
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 2854d85..7e2e8cd 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -241,14 +241,11 @@
 
 static int __init i2c_parport_init(void)
 {
-	int type_count;
-
-	type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm);
-	if (type < 0 || type >= type_count) {
+	if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
 		printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
 		type = 0;
 	}
-	
+
 	return parport_register_driver(&i2c_parport_driver);
 }
 
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 86e2234..7579f4b2 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -861,7 +861,7 @@
 		decode_ISR(isr);
 	}
 
-	if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32))
+	if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog))
 		i2c->isrlog[i2c->irqlogidx++] = isr;
 
 	show_state(i2c);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 0ce58b5..1a2c9ab 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -946,6 +946,20 @@
 	}
 }
 
+s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
+				   u8 length, u8 *values)
+{
+	union i2c_smbus_data data;
+
+	if (length > I2C_SMBUS_BLOCK_MAX)
+		length = I2C_SMBUS_BLOCK_MAX;
+	data.block[0] = length;
+	memcpy(data.block + 1, values, length);
+	return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+			      I2C_SMBUS_WRITE, command,
+			      I2C_SMBUS_I2C_BLOCK_DATA, &data);
+}
+
 /* Simulate a SMBus command using the i2c protocol 
    No checking of parameters is done!  */
 static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, 
@@ -1150,6 +1164,7 @@
 EXPORT_SYMBOL(i2c_smbus_write_word_data);
 EXPORT_SYMBOL(i2c_smbus_write_block_data);
 EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
+EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 6c60a9d..09086b8 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -190,7 +190,8 @@
 		if (lba48) {
 			task_ioreg_t tasklets[10];
 
-			pr_debug("%s: LBA=0x%012llx\n", drive->name, block);
+			pr_debug("%s: LBA=0x%012llx\n", drive->name,
+					(unsigned long long)block);
 
 			tasklets[0] = 0;
 			tasklets[1] = 0;
@@ -317,7 +318,8 @@
 
 	pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
 		 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
-		 block, rq->nr_sectors, (unsigned long)rq->buffer);
+		 (unsigned long long)block, rq->nr_sectors,
+		 (unsigned long)rq->buffer);
 
 	if (hwif->rw_disk)
 		hwif->rw_disk(drive, rq);
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index e95c429..f6a0596 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -1319,15 +1319,6 @@
 	.release = ib_ucm_release_class_dev
 };
 
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
-	struct ib_ucm_device *dev;
-	
-	dev = container_of(class_dev, struct ib_ucm_device, class_dev);
-	return print_dev_t(buf, dev->dev.dev);
-}
-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
-
 static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
 {
 	struct ib_ucm_device *dev;
@@ -1364,15 +1355,13 @@
 
 	ucm_dev->class_dev.class = &ucm_class;
 	ucm_dev->class_dev.dev = device->dma_device;
+	ucm_dev->class_dev.devt = ucm_dev->dev.dev;
 	snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
 		 ucm_dev->devnum);
 	if (class_device_register(&ucm_dev->class_dev))
 		goto err_cdev;
 
 	if (class_device_create_file(&ucm_dev->class_dev,
-				     &class_device_attr_dev))
-		goto err_class;
-	if (class_device_create_file(&ucm_dev->class_dev,
 				     &class_device_attr_ibdev))
 		goto err_class;
 
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 0ef5601..6dfc941 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -351,7 +351,7 @@
 
 config HISAX_AMD7930
 	bool "Am7930 (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && SPARC
+	depends on EXPERIMENTAL && SPARC && BROKEN
 	help
 	  This enables HiSax support for the AMD7930 chips on some SPARCs.
 	  This code is not finished yet.
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 7d4a0ac..12ad462 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -187,6 +187,14 @@
 	  This driver provides thermal control for the PowerMac9,1
           which is the recent (SMU based) single CPU desktop G5
 
+config WINDFARM_PM112
+	tristate "Support for thermal management on PowerMac11,2"
+	depends on WINDFARM && I2C && PMAC_SMU
+	select I2C_POWERMAC
+	help
+	  This driver provides thermal control for the PowerMac11,2
+	  which are the recent dual and quad G5 machines using the
+	  970MP dual-core processor.
 
 config ANSLCD
 	tristate "Support for ANS LCD display"
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index f4657aa..6081acd 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -35,3 +35,8 @@
 				   windfarm_smu_sensors.o \
 				   windfarm_lm75_sensor.o windfarm_pid.o \
 				   windfarm_cpufreq_clamp.o windfarm_pm91.o
+obj-$(CONFIG_WINDFARM_PM112)	+= windfarm_pm112.o windfarm_smu_sat.o \
+				   windfarm_smu_controls.o \
+				   windfarm_smu_sensors.o \
+				   windfarm_max6690_sensor.o \
+				   windfarm_lm75_sensor.o windfarm_pid.o
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h
index 3f0cb03..7a2482c 100644
--- a/drivers/macintosh/windfarm.h
+++ b/drivers/macintosh/windfarm.h
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
+#include <linux/device.h>
 
 /* Display a 16.16 fixed point value */
 #define FIX32TOPRINT(f)	((f) >> 16),((((f) & 0xffff) * 1000) >> 16)
@@ -39,6 +40,7 @@
 	char			*name;
 	int			type;
 	struct kref		ref;
+	struct device_attribute	attr;
 };
 
 #define WF_CONTROL_TYPE_GENERIC		0
@@ -87,6 +89,7 @@
 	struct wf_sensor_ops	*ops;
 	char			*name;
 	struct kref		ref;
+	struct device_attribute	attr;
 };
 
 /* Same lifetime rules as controls */
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 6c2a471..bb8d5ef 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -33,6 +33,7 @@
 #include <linux/reboot.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/mutex.h>
 
 #include "windfarm.h"
 
@@ -48,13 +49,17 @@
 
 static LIST_HEAD(wf_controls);
 static LIST_HEAD(wf_sensors);
-static DECLARE_MUTEX(wf_lock);
+static DEFINE_MUTEX(wf_lock);
 static struct notifier_block *wf_client_list;
 static int wf_client_count;
 static unsigned int wf_overtemp;
 static unsigned int wf_overtemp_counter;
 struct task_struct *wf_thread;
 
+static struct platform_device wf_platform_device = {
+	.name	= "windfarm",
+};
+
 /*
  * Utilities & tick thread
  */
@@ -156,26 +161,67 @@
 		kfree(ct);
 }
 
+static ssize_t wf_show_control(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
+	s32 val = 0;
+	int err;
+
+	err = ctrl->ops->get_value(ctrl, &val);
+	if (err < 0)
+		return err;
+	return sprintf(buf, "%d\n", val);
+}
+
+/* This is really only for debugging... */
+static ssize_t wf_store_control(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
+	int val;
+	int err;
+	char *endp;
+
+	val = simple_strtoul(buf, &endp, 0);
+	while (endp < buf + count && (*endp == ' ' || *endp == '\n'))
+		++endp;
+	if (endp - buf < count)
+		return -EINVAL;
+	err = ctrl->ops->set_value(ctrl, val);
+	if (err < 0)
+		return err;
+	return count;
+}
+
 int wf_register_control(struct wf_control *new_ct)
 {
 	struct wf_control *ct;
 
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	list_for_each_entry(ct, &wf_controls, link) {
 		if (!strcmp(ct->name, new_ct->name)) {
 			printk(KERN_WARNING "windfarm: trying to register"
 			       " duplicate control %s\n", ct->name);
-			up(&wf_lock);
+			mutex_unlock(&wf_lock);
 			return -EEXIST;
 		}
 	}
 	kref_init(&new_ct->ref);
 	list_add(&new_ct->link, &wf_controls);
 
+	new_ct->attr.attr.name = new_ct->name;
+	new_ct->attr.attr.owner = THIS_MODULE;
+	new_ct->attr.attr.mode = 0644;
+	new_ct->attr.show = wf_show_control;
+	new_ct->attr.store = wf_store_control;
+	device_create_file(&wf_platform_device.dev, &new_ct->attr);
+
 	DBG("wf: Registered control %s\n", new_ct->name);
 
 	wf_notify(WF_EVENT_NEW_CONTROL, new_ct);
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 
 	return 0;
 }
@@ -183,9 +229,9 @@
 
 void wf_unregister_control(struct wf_control *ct)
 {
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	list_del(&ct->link);
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 
 	DBG("wf: Unregistered control %s\n", ct->name);
 
@@ -197,16 +243,16 @@
 {
 	struct wf_control *ct;
 
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	list_for_each_entry(ct, &wf_controls, link) {
 		if (!strcmp(ct->name, name)) {
 			if (wf_get_control(ct))
 				ct = NULL;
-			up(&wf_lock);
+			mutex_unlock(&wf_lock);
 			return ct;
 		}
 	}
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(wf_find_control);
@@ -246,26 +292,46 @@
 		kfree(sr);
 }
 
+static ssize_t wf_show_sensor(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr);
+	s32 val = 0;
+	int err;
+
+	err = sens->ops->get_value(sens, &val);
+	if (err < 0)
+		return err;
+	return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val));
+}
+
 int wf_register_sensor(struct wf_sensor *new_sr)
 {
 	struct wf_sensor *sr;
 
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	list_for_each_entry(sr, &wf_sensors, link) {
 		if (!strcmp(sr->name, new_sr->name)) {
 			printk(KERN_WARNING "windfarm: trying to register"
 			       " duplicate sensor %s\n", sr->name);
-			up(&wf_lock);
+			mutex_unlock(&wf_lock);
 			return -EEXIST;
 		}
 	}
 	kref_init(&new_sr->ref);
 	list_add(&new_sr->link, &wf_sensors);
 
+	new_sr->attr.attr.name = new_sr->name;
+	new_sr->attr.attr.owner = THIS_MODULE;
+	new_sr->attr.attr.mode = 0444;
+	new_sr->attr.show = wf_show_sensor;
+	new_sr->attr.store = NULL;
+	device_create_file(&wf_platform_device.dev, &new_sr->attr);
+
 	DBG("wf: Registered sensor %s\n", new_sr->name);
 
 	wf_notify(WF_EVENT_NEW_SENSOR, new_sr);
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 
 	return 0;
 }
@@ -273,9 +339,9 @@
 
 void wf_unregister_sensor(struct wf_sensor *sr)
 {
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	list_del(&sr->link);
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 
 	DBG("wf: Unregistered sensor %s\n", sr->name);
 
@@ -287,16 +353,16 @@
 {
 	struct wf_sensor *sr;
 
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	list_for_each_entry(sr, &wf_sensors, link) {
 		if (!strcmp(sr->name, name)) {
 			if (wf_get_sensor(sr))
 				sr = NULL;
-			up(&wf_lock);
+			mutex_unlock(&wf_lock);
 			return sr;
 		}
 	}
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(wf_find_sensor);
@@ -329,7 +395,7 @@
 	struct wf_control *ct;
 	struct wf_sensor *sr;
 
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	rc = notifier_chain_register(&wf_client_list, nb);
 	if (rc != 0)
 		goto bail;
@@ -341,19 +407,19 @@
 	if (wf_client_count == 1)
 		wf_start_thread();
  bail:
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(wf_register_client);
 
 int wf_unregister_client(struct notifier_block *nb)
 {
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	notifier_chain_unregister(&wf_client_list, nb);
 	wf_client_count++;
 	if (wf_client_count == 0)
 		wf_stop_thread();
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 
 	return 0;
 }
@@ -361,23 +427,23 @@
 
 void wf_set_overtemp(void)
 {
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	wf_overtemp++;
 	if (wf_overtemp == 1) {
 		printk(KERN_WARNING "windfarm: Overtemp condition detected !\n");
 		wf_overtemp_counter = 0;
 		wf_notify(WF_EVENT_OVERTEMP, NULL);
 	}
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 }
 EXPORT_SYMBOL_GPL(wf_set_overtemp);
 
 void wf_clear_overtemp(void)
 {
-	down(&wf_lock);
+	mutex_lock(&wf_lock);
 	WARN_ON(wf_overtemp == 0);
 	if (wf_overtemp == 0) {
-		up(&wf_lock);
+		mutex_unlock(&wf_lock);
 		return;
 	}
 	wf_overtemp--;
@@ -385,7 +451,7 @@
 		printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n");
 		wf_notify(WF_EVENT_NORMALTEMP, NULL);
 	}
-	up(&wf_lock);
+	mutex_unlock(&wf_lock);
 }
 EXPORT_SYMBOL_GPL(wf_clear_overtemp);
 
@@ -395,10 +461,6 @@
 }
 EXPORT_SYMBOL_GPL(wf_is_overtemp);
 
-static struct platform_device wf_platform_device = {
-	.name	= "windfarm",
-};
-
 static int __init windfarm_core_init(void)
 {
 	DBG("wf: core loaded\n");
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
new file mode 100644
index 0000000..5b9ad6ca
--- /dev/null
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -0,0 +1,169 @@
+/*
+ * Windfarm PowerMac thermal control.  MAX6690 sensor.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ *
+ * Use and redistribute under the terms of the GNU GPL v2.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/prom.h>
+#include <asm/pmac_low_i2c.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.1"
+
+/* This currently only exports the external temperature sensor,
+   since that's all the control loops need. */
+
+/* Some MAX6690 register numbers */
+#define MAX6690_INTERNAL_TEMP	0
+#define MAX6690_EXTERNAL_TEMP	1
+
+struct wf_6690_sensor {
+	struct i2c_client	i2c;
+	struct wf_sensor	sens;
+};
+
+#define wf_to_6690(x)	container_of((x), struct wf_6690_sensor, sens)
+#define i2c_to_6690(x)	container_of((x), struct wf_6690_sensor, i2c)
+
+static int wf_max6690_attach(struct i2c_adapter *adapter);
+static int wf_max6690_detach(struct i2c_client *client);
+
+static struct i2c_driver wf_max6690_driver = {
+	.driver = {
+		.name		= "wf_max6690",
+	},
+	.attach_adapter	= wf_max6690_attach,
+	.detach_client	= wf_max6690_detach,
+};
+
+static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
+{
+	struct wf_6690_sensor *max = wf_to_6690(sr);
+	s32 data;
+
+	if (max->i2c.adapter == NULL)
+		return -ENODEV;
+
+	/* chip gets initialized by firmware */
+	data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP);
+	if (data < 0)
+		return data;
+	*value = data << 16;
+	return 0;
+}
+
+static void wf_max6690_release(struct wf_sensor *sr)
+{
+	struct wf_6690_sensor *max = wf_to_6690(sr);
+
+	if (max->i2c.adapter) {
+		i2c_detach_client(&max->i2c);
+		max->i2c.adapter = NULL;
+	}
+	kfree(max);
+}
+
+static struct wf_sensor_ops wf_max6690_ops = {
+	.get_value	= wf_max6690_get,
+	.release	= wf_max6690_release,
+	.owner		= THIS_MODULE,
+};
+
+static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr)
+{
+	struct wf_6690_sensor *max;
+	char *name = "u4-temp";
+
+	max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
+	if (max == NULL) {
+		printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
+		       "no memory\n", name);
+		return;
+	}
+
+	max->sens.ops = &wf_max6690_ops;
+	max->sens.name = name;
+	max->i2c.addr = addr >> 1;
+	max->i2c.adapter = adapter;
+	max->i2c.driver = &wf_max6690_driver;
+	strncpy(max->i2c.name, name, I2C_NAME_SIZE-1);
+
+	if (i2c_attach_client(&max->i2c)) {
+		printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
+		goto fail;
+	}
+
+	if (wf_register_sensor(&max->sens)) {
+		i2c_detach_client(&max->i2c);
+		goto fail;
+	}
+
+	return;
+
+ fail:
+	kfree(max);
+}
+
+static int wf_max6690_attach(struct i2c_adapter *adapter)
+{
+	struct device_node *busnode, *dev = NULL;
+	struct pmac_i2c_bus *bus;
+	const char *loc;
+	u32 *reg;
+
+	bus = pmac_i2c_adapter_to_bus(adapter);
+	if (bus == NULL)
+		return -ENODEV;
+	busnode = pmac_i2c_get_bus_node(bus);
+
+	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
+		if (!device_is_compatible(dev, "max6690"))
+			continue;
+		loc = get_property(dev, "hwsensor-location", NULL);
+		reg = (u32 *) get_property(dev, "reg", NULL);
+		if (!loc || !reg)
+			continue;
+		printk("found max6690, loc=%s reg=%x\n", loc, *reg);
+		if (strcmp(loc, "BACKSIDE"))
+			continue;
+		wf_max6690_create(adapter, *reg);
+	}
+
+	return 0;
+}
+
+static int wf_max6690_detach(struct i2c_client *client)
+{
+	struct wf_6690_sensor *max = i2c_to_6690(client);
+
+	max->i2c.adapter = NULL;
+	wf_unregister_sensor(&max->sens);
+
+	return 0;
+}
+
+static int __init wf_max6690_sensor_init(void)
+{
+	return i2c_add_driver(&wf_max6690_driver);
+}
+
+static void __exit wf_max6690_sensor_exit(void)
+{
+	i2c_del_driver(&wf_max6690_driver);
+}
+
+module_init(wf_max6690_sensor_init);
+module_exit(wf_max6690_sensor_exit);
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control");
+MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c
index 2e803b3..0842432 100644
--- a/drivers/macintosh/windfarm_pid.c
+++ b/drivers/macintosh/windfarm_pid.c
@@ -88,8 +88,8 @@
 
 s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
 {
-	s64	error, integ, deriv, prop;
-	s32	target, sval, adj;
+	s64	integ, deriv, prop;
+	s32	error, target, sval, adj;
 	int	i, hlen = st->param.history_len;
 
 	/* Calculate error term */
@@ -117,7 +117,7 @@
 		integ += st->errors[(st->index + hlen - i) % hlen];
 	integ *= st->param.interval;
 	integ *= st->param.gr;
-	sval = st->param.tmax - ((integ >> 20) & 0xffffffff);
+	sval = st->param.tmax - (s32)(integ >> 20);
 	adj = min(st->param.ttarget, sval);
 
 	DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj);
@@ -129,7 +129,7 @@
 	deriv *= st->param.gd;
 
 	/* Calculate proportional term */
-	prop = (new_temp - adj);
+	prop = st->last_delta = (new_temp - adj);
 	prop *= st->param.gp;
 
 	DBG("deriv: %lx, prop: %lx\n", deriv, prop);
diff --git a/drivers/macintosh/windfarm_pid.h b/drivers/macintosh/windfarm_pid.h
index a364c2a..bbccc22 100644
--- a/drivers/macintosh/windfarm_pid.h
+++ b/drivers/macintosh/windfarm_pid.h
@@ -72,6 +72,7 @@
 	int	index; 				/* index of current power */
 	int	tindex; 			/* index of current temp */
 	s32	target;				/* current target value */
+	s32	last_delta;			/* last Tactual - Ttarget */
 	s32	powers[WF_PID_MAX_HISTORY];	/* power history buffer */
 	s32	errors[WF_PID_MAX_HISTORY];	/* error history buffer */
 	s32	temps[2];			/* temp. history buffer */
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
new file mode 100644
index 0000000..c2a4e68
--- /dev/null
+++ b/drivers/macintosh/windfarm_pm112.c
@@ -0,0 +1,698 @@
+/*
+ * Windfarm PowerMac thermal control.
+ * Control loops for machines with SMU and PPC970MP processors.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *
+ * Use and redistribute under the terms of the GNU GPL v2.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <asm/prom.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+#include "windfarm_pid.h"
+
+#define VERSION "0.2"
+
+#define DEBUG
+#undef LOTSA_DEBUG
+
+#ifdef DEBUG
+#define DBG(args...)	printk(args)
+#else
+#define DBG(args...)	do { } while(0)
+#endif
+
+#ifdef LOTSA_DEBUG
+#define DBG_LOTS(args...)	printk(args)
+#else
+#define DBG_LOTS(args...)	do { } while(0)
+#endif
+
+/* define this to force CPU overtemp to 60 degree, useful for testing
+ * the overtemp code
+ */
+#undef HACKED_OVERTEMP
+
+/* We currently only handle 2 chips, 4 cores... */
+#define NR_CHIPS	2
+#define NR_CORES	4
+#define NR_CPU_FANS	3 * NR_CHIPS
+
+/* Controls and sensors */
+static struct wf_sensor *sens_cpu_temp[NR_CORES];
+static struct wf_sensor *sens_cpu_power[NR_CORES];
+static struct wf_sensor *hd_temp;
+static struct wf_sensor *slots_power;
+static struct wf_sensor *u4_temp;
+
+static struct wf_control *cpu_fans[NR_CPU_FANS];
+static char *cpu_fan_names[NR_CPU_FANS] = {
+	"cpu-rear-fan-0",
+	"cpu-rear-fan-1",
+	"cpu-front-fan-0",
+	"cpu-front-fan-1",
+	"cpu-pump-0",
+	"cpu-pump-1",
+};
+static struct wf_control *cpufreq_clamp;
+
+/* Second pump isn't required (and isn't actually present) */
+#define CPU_FANS_REQD		(NR_CPU_FANS - 2)
+#define FIRST_PUMP		4
+#define LAST_PUMP		5
+
+/* We keep a temperature history for average calculation of 180s */
+#define CPU_TEMP_HIST_SIZE	180
+
+/* Scale factor for fan speed, *100 */
+static int cpu_fan_scale[NR_CPU_FANS] = {
+	100,
+	100,
+	97,		/* inlet fans run at 97% of exhaust fan */
+	97,
+	100,		/* updated later */
+	100,		/* updated later */
+};
+
+static struct wf_control *backside_fan;
+static struct wf_control *slots_fan;
+static struct wf_control *drive_bay_fan;
+
+/* PID loop state */
+static struct wf_cpu_pid_state cpu_pid[NR_CORES];
+static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
+static int cpu_thist_pt;
+static s64 cpu_thist_total;
+static s32 cpu_all_tmax = 100 << 16;
+static int cpu_last_target;
+static struct wf_pid_state backside_pid;
+static int backside_tick;
+static struct wf_pid_state slots_pid;
+static int slots_started;
+static struct wf_pid_state drive_bay_pid;
+static int drive_bay_tick;
+
+static int nr_cores;
+static int have_all_controls;
+static int have_all_sensors;
+static int started;
+
+static int failure_state;
+#define FAILURE_SENSOR		1
+#define FAILURE_FAN		2
+#define FAILURE_PERM		4
+#define FAILURE_LOW_OVERTEMP	8
+#define FAILURE_HIGH_OVERTEMP	16
+
+/* Overtemp values */
+#define LOW_OVER_AVERAGE	0
+#define LOW_OVER_IMMEDIATE	(10 << 16)
+#define LOW_OVER_CLEAR		((-10) << 16)
+#define HIGH_OVER_IMMEDIATE	(14 << 16)
+#define HIGH_OVER_AVERAGE	(10 << 16)
+#define HIGH_OVER_IMMEDIATE	(14 << 16)
+
+
+/* Implementation... */
+static int create_cpu_loop(int cpu)
+{
+	int chip = cpu / 2;
+	int core = cpu & 1;
+	struct smu_sdbp_header *hdr;
+	struct smu_sdbp_cpupiddata *piddata;
+	struct wf_cpu_pid_param pid;
+	struct wf_control *main_fan = cpu_fans[0];
+	s32 tmax;
+	int fmin;
+
+	/* Get PID params from the appropriate SAT */
+	hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
+	if (hdr == NULL) {
+		printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
+		return -EINVAL;
+	}
+	piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
+
+	/* Get FVT params to get Tmax; if not found, assume default */
+	hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
+	if (hdr) {
+		struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1];
+		tmax = fvt->maxtemp << 16;
+	} else
+		tmax = 95 << 16;	/* default to 95 degrees C */
+
+	/* We keep a global tmax for overtemp calculations */
+	if (tmax < cpu_all_tmax)
+		cpu_all_tmax = tmax;
+
+	/*
+	 * Darwin has a minimum fan speed of 1000 rpm for the 4-way and
+	 * 515 for the 2-way.  That appears to be overkill, so for now,
+	 * impose a minimum of 750 or 515.
+	 */
+	fmin = (nr_cores > 2) ? 750 : 515;
+
+	/* Initialize PID loop */
+	pid.interval = 1;	/* seconds */
+	pid.history_len = piddata->history_len;
+	pid.gd = piddata->gd;
+	pid.gp = piddata->gp;
+	pid.gr = piddata->gr / piddata->history_len;
+	pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8);
+	pid.ttarget = tmax - (piddata->target_temp_delta << 16);
+	pid.tmax = tmax;
+	pid.min = main_fan->ops->get_min(main_fan);
+	pid.max = main_fan->ops->get_max(main_fan);
+	if (pid.min < fmin)
+		pid.min = fmin;
+
+	wf_cpu_pid_init(&cpu_pid[cpu], &pid);
+	return 0;
+}
+
+static void cpu_max_all_fans(void)
+{
+	int i;
+
+	/* We max all CPU fans in case of a sensor error. We also do the
+	 * cpufreq clamping now, even if it's supposedly done later by the
+	 * generic code anyway, we do it earlier here to react faster
+	 */
+	if (cpufreq_clamp)
+		wf_control_set_max(cpufreq_clamp);
+	for (i = 0; i < NR_CPU_FANS; ++i)
+		if (cpu_fans[i])
+			wf_control_set_max(cpu_fans[i]);
+}
+
+static int cpu_check_overtemp(s32 temp)
+{
+	int new_state = 0;
+	s32 t_avg, t_old;
+
+	/* First check for immediate overtemps */
+	if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
+		new_state |= FAILURE_LOW_OVERTEMP;
+		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
+			printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
+			       " temperature !\n");
+	}
+	if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
+		new_state |= FAILURE_HIGH_OVERTEMP;
+		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
+			printk(KERN_ERR "windfarm: Critical overtemp due to"
+			       " immediate CPU temperature !\n");
+	}
+
+	/* We calculate a history of max temperatures and use that for the
+	 * overtemp management
+	 */
+	t_old = cpu_thist[cpu_thist_pt];
+	cpu_thist[cpu_thist_pt] = temp;
+	cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
+	cpu_thist_total -= t_old;
+	cpu_thist_total += temp;
+	t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
+
+	DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
+		 FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
+
+	/* Now check for average overtemps */
+	if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
+		new_state |= FAILURE_LOW_OVERTEMP;
+		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
+			printk(KERN_ERR "windfarm: Overtemp due to average CPU"
+			       " temperature !\n");
+	}
+	if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
+		new_state |= FAILURE_HIGH_OVERTEMP;
+		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
+			printk(KERN_ERR "windfarm: Critical overtemp due to"
+			       " average CPU temperature !\n");
+	}
+
+	/* Now handle overtemp conditions. We don't currently use the windfarm
+	 * overtemp handling core as it's not fully suited to the needs of those
+	 * new machine. This will be fixed later.
+	 */
+	if (new_state) {
+		/* High overtemp -> immediate shutdown */
+		if (new_state & FAILURE_HIGH_OVERTEMP)
+			machine_power_off();
+		if ((failure_state & new_state) != new_state)
+			cpu_max_all_fans();
+		failure_state |= new_state;
+	} else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
+		   (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
+		printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
+		failure_state &= ~FAILURE_LOW_OVERTEMP;
+	}
+
+	return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
+}
+
+static void cpu_fans_tick(void)
+{
+	int err, cpu;
+	s32 greatest_delta = 0;
+	s32 temp, power, t_max = 0;
+	int i, t, target = 0;
+	struct wf_sensor *sr;
+	struct wf_control *ct;
+	struct wf_cpu_pid_state *sp;
+
+	DBG_LOTS(KERN_DEBUG);
+	for (cpu = 0; cpu < nr_cores; ++cpu) {
+		/* Get CPU core temperature */
+		sr = sens_cpu_temp[cpu];
+		err = sr->ops->get_value(sr, &temp);
+		if (err) {
+			DBG("\n");
+			printk(KERN_WARNING "windfarm: CPU %d temperature "
+			       "sensor error %d\n", cpu, err);
+			failure_state |= FAILURE_SENSOR;
+			cpu_max_all_fans();
+			return;
+		}
+
+		/* Keep track of highest temp */
+		t_max = max(t_max, temp);
+
+		/* Get CPU power */
+		sr = sens_cpu_power[cpu];
+		err = sr->ops->get_value(sr, &power);
+		if (err) {
+			DBG("\n");
+			printk(KERN_WARNING "windfarm: CPU %d power "
+			       "sensor error %d\n", cpu, err);
+			failure_state |= FAILURE_SENSOR;
+			cpu_max_all_fans();
+			return;
+		}
+
+		/* Run PID */
+		sp = &cpu_pid[cpu];
+		t = wf_cpu_pid_run(sp, power, temp);
+
+		if (cpu == 0 || sp->last_delta > greatest_delta) {
+			greatest_delta = sp->last_delta;
+			target = t;
+		}
+		DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ",
+		    cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp));
+	}
+	DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max));
+
+	/* Darwin limits decrease to 20 per iteration */
+	if (target < (cpu_last_target - 20))
+		target = cpu_last_target - 20;
+	cpu_last_target = target;
+	for (cpu = 0; cpu < nr_cores; ++cpu)
+		cpu_pid[cpu].target = target;
+
+	/* Handle possible overtemps */
+	if (cpu_check_overtemp(t_max))
+		return;
+
+	/* Set fans */
+	for (i = 0; i < NR_CPU_FANS; ++i) {
+		ct = cpu_fans[i];
+		if (ct == NULL)
+			continue;
+		err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100);
+		if (err) {
+			printk(KERN_WARNING "windfarm: fan %s reports "
+			       "error %d\n", ct->name, err);
+			failure_state |= FAILURE_FAN;
+			break;
+		}
+	}
+}
+
+/* Backside/U4 fan */
+static struct wf_pid_param backside_param = {
+	.interval	= 5,
+	.history_len	= 2,
+	.gd		= 48 << 20,
+	.gp		= 5 << 20,
+	.gr		= 0,
+	.itarget	= 64 << 16,
+	.additive	= 1,
+};
+
+static void backside_fan_tick(void)
+{
+	s32 temp;
+	int speed;
+	int err;
+
+	if (!backside_fan || !u4_temp)
+		return;
+	if (!backside_tick) {
+		/* first time; initialize things */
+		backside_param.min = backside_fan->ops->get_min(backside_fan);
+		backside_param.max = backside_fan->ops->get_max(backside_fan);
+		wf_pid_init(&backside_pid, &backside_param);
+		backside_tick = 1;
+	}
+	if (--backside_tick > 0)
+		return;
+	backside_tick = backside_pid.param.interval;
+
+	err = u4_temp->ops->get_value(u4_temp, &temp);
+	if (err) {
+		printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n",
+		       err);
+		failure_state |= FAILURE_SENSOR;
+		wf_control_set_max(backside_fan);
+		return;
+	}
+	speed = wf_pid_run(&backside_pid, temp);
+	DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
+		 FIX32TOPRINT(temp), speed);
+
+	err = backside_fan->ops->set_value(backside_fan, speed);
+	if (err) {
+		printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
+		failure_state |= FAILURE_FAN;
+	}
+}
+
+/* Drive bay fan */
+static struct wf_pid_param drive_bay_prm = {
+	.interval	= 5,
+	.history_len	= 2,
+	.gd		= 30 << 20,
+	.gp		= 5 << 20,
+	.gr		= 0,
+	.itarget	= 40 << 16,
+	.additive	= 1,
+};
+
+static void drive_bay_fan_tick(void)
+{
+	s32 temp;
+	int speed;
+	int err;
+
+	if (!drive_bay_fan || !hd_temp)
+		return;
+	if (!drive_bay_tick) {
+		/* first time; initialize things */
+		drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan);
+		drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan);
+		wf_pid_init(&drive_bay_pid, &drive_bay_prm);
+		drive_bay_tick = 1;
+	}
+	if (--drive_bay_tick > 0)
+		return;
+	drive_bay_tick = drive_bay_pid.param.interval;
+
+	err = hd_temp->ops->get_value(hd_temp, &temp);
+	if (err) {
+		printk(KERN_WARNING "windfarm: drive bay temp sensor "
+		       "error %d\n", err);
+		failure_state |= FAILURE_SENSOR;
+		wf_control_set_max(drive_bay_fan);
+		return;
+	}
+	speed = wf_pid_run(&drive_bay_pid, temp);
+	DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n",
+		 FIX32TOPRINT(temp), speed);
+
+	err = drive_bay_fan->ops->set_value(drive_bay_fan, speed);
+	if (err) {
+		printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err);
+		failure_state |= FAILURE_FAN;
+	}
+}
+
+/* PCI slots area fan */
+/* This makes the fan speed proportional to the power consumed */
+static struct wf_pid_param slots_param = {
+	.interval	= 1,
+	.history_len	= 2,
+	.gd		= 0,
+	.gp		= 0,
+	.gr		= 0x1277952,
+	.itarget	= 0,
+	.min		= 1560,
+	.max		= 3510,
+};
+
+static void slots_fan_tick(void)
+{
+	s32 power;
+	int speed;
+	int err;
+
+	if (!slots_fan || !slots_power)
+		return;
+	if (!slots_started) {
+		/* first time; initialize things */
+		wf_pid_init(&slots_pid, &slots_param);
+		slots_started = 1;
+	}
+
+	err = slots_power->ops->get_value(slots_power, &power);
+	if (err) {
+		printk(KERN_WARNING "windfarm: slots power sensor error %d\n",
+		       err);
+		failure_state |= FAILURE_SENSOR;
+		wf_control_set_max(slots_fan);
+		return;
+	}
+	speed = wf_pid_run(&slots_pid, power);
+	DBG_LOTS("slots PID power=%d.%.3d speed=%d\n",
+		 FIX32TOPRINT(power), speed);
+
+	err = slots_fan->ops->set_value(slots_fan, speed);
+	if (err) {
+		printk(KERN_WARNING "windfarm: slots fan error %d\n", err);
+		failure_state |= FAILURE_FAN;
+	}
+}
+
+static void set_fail_state(void)
+{
+	int i;
+
+	if (cpufreq_clamp)
+		wf_control_set_max(cpufreq_clamp);
+	for (i = 0; i < NR_CPU_FANS; ++i)
+		if (cpu_fans[i])
+			wf_control_set_max(cpu_fans[i]);
+	if (backside_fan)
+		wf_control_set_max(backside_fan);
+	if (slots_fan)
+		wf_control_set_max(slots_fan);
+	if (drive_bay_fan)
+		wf_control_set_max(drive_bay_fan);
+}
+
+static void pm112_tick(void)
+{
+	int i, last_failure;
+
+	if (!started) {
+		started = 1;
+		for (i = 0; i < nr_cores; ++i) {
+			if (create_cpu_loop(i) < 0) {
+				failure_state = FAILURE_PERM;
+				set_fail_state();
+				break;
+			}
+		}
+		DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
+
+#ifdef HACKED_OVERTEMP
+		cpu_all_tmax = 60 << 16;
+#endif
+	}
+
+	/* Permanent failure, bail out */
+	if (failure_state & FAILURE_PERM)
+		return;
+	/* Clear all failure bits except low overtemp which will be eventually
+	 * cleared by the control loop itself
+	 */
+	last_failure = failure_state;
+	failure_state &= FAILURE_LOW_OVERTEMP;
+	cpu_fans_tick();
+	backside_fan_tick();
+	slots_fan_tick();
+	drive_bay_fan_tick();
+
+	DBG_LOTS("last_failure: 0x%x, failure_state: %x\n",
+		 last_failure, failure_state);
+
+	/* Check for failures. Any failure causes cpufreq clamping */
+	if (failure_state && last_failure == 0 && cpufreq_clamp)
+		wf_control_set_max(cpufreq_clamp);
+	if (failure_state == 0 && last_failure && cpufreq_clamp)
+		wf_control_set_min(cpufreq_clamp);
+
+	/* That's it for now, we might want to deal with other failures
+	 * differently in the future though
+	 */
+}
+
+static void pm112_new_control(struct wf_control *ct)
+{
+	int i, max_exhaust;
+
+	if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
+		if (wf_get_control(ct) == 0)
+			cpufreq_clamp = ct;
+	}
+
+	for (i = 0; i < NR_CPU_FANS; ++i) {
+		if (!strcmp(ct->name, cpu_fan_names[i])) {
+			if (cpu_fans[i] == NULL && wf_get_control(ct) == 0)
+				cpu_fans[i] = ct;
+			break;
+		}
+	}
+	if (i >= NR_CPU_FANS) {
+		/* not a CPU fan, try the others */
+		if (!strcmp(ct->name, "backside-fan")) {
+			if (backside_fan == NULL && wf_get_control(ct) == 0)
+				backside_fan = ct;
+		} else if (!strcmp(ct->name, "slots-fan")) {
+			if (slots_fan == NULL && wf_get_control(ct) == 0)
+				slots_fan = ct;
+		} else if (!strcmp(ct->name, "drive-bay-fan")) {
+			if (drive_bay_fan == NULL && wf_get_control(ct) == 0)
+				drive_bay_fan = ct;
+		}
+		return;
+	}
+
+	for (i = 0; i < CPU_FANS_REQD; ++i)
+		if (cpu_fans[i] == NULL)
+			return;
+
+	/* work out pump scaling factors */
+	max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]);
+	for (i = FIRST_PUMP; i <= LAST_PUMP; ++i)
+		if ((ct = cpu_fans[i]) != NULL)
+			cpu_fan_scale[i] =
+				ct->ops->get_max(ct) * 100 / max_exhaust;
+
+	have_all_controls = 1;
+}
+
+static void pm112_new_sensor(struct wf_sensor *sr)
+{
+	unsigned int i;
+
+	if (have_all_sensors)
+		return;
+	if (!strncmp(sr->name, "cpu-temp-", 9)) {
+		i = sr->name[9] - '0';
+		if (sr->name[10] == 0 && i < NR_CORES &&
+		    sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0)
+			sens_cpu_temp[i] = sr;
+
+	} else if (!strncmp(sr->name, "cpu-power-", 10)) {
+		i = sr->name[10] - '0';
+		if (sr->name[11] == 0 && i < NR_CORES &&
+		    sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0)
+			sens_cpu_power[i] = sr;
+	} else if (!strcmp(sr->name, "hd-temp")) {
+		if (hd_temp == NULL && wf_get_sensor(sr) == 0)
+			hd_temp = sr;
+	} else if (!strcmp(sr->name, "slots-power")) {
+		if (slots_power == NULL && wf_get_sensor(sr) == 0)
+			slots_power = sr;
+	} else if (!strcmp(sr->name, "u4-temp")) {
+		if (u4_temp == NULL && wf_get_sensor(sr) == 0)
+			u4_temp = sr;
+	} else
+		return;
+
+	/* check if we have all the sensors we need */
+	for (i = 0; i < nr_cores; ++i)
+		if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL)
+			return;
+
+	have_all_sensors = 1;
+}
+
+static int pm112_wf_notify(struct notifier_block *self,
+			   unsigned long event, void *data)
+{
+	switch (event) {
+	case WF_EVENT_NEW_SENSOR:
+		pm112_new_sensor(data);
+		break;
+	case WF_EVENT_NEW_CONTROL:
+		pm112_new_control(data);
+		break;
+	case WF_EVENT_TICK:
+		if (have_all_controls && have_all_sensors)
+			pm112_tick();
+	}
+	return 0;
+}
+
+static struct notifier_block pm112_events = {
+	.notifier_call = pm112_wf_notify,
+};
+
+static int wf_pm112_probe(struct device *dev)
+{
+	wf_register_client(&pm112_events);
+	return 0;
+}
+
+static int wf_pm112_remove(struct device *dev)
+{
+	wf_unregister_client(&pm112_events);
+	/* should release all sensors and controls */
+	return 0;
+}
+
+static struct device_driver wf_pm112_driver = {
+	.name = "windfarm",
+	.bus = &platform_bus_type,
+	.probe = wf_pm112_probe,
+	.remove = wf_pm112_remove,
+};
+
+static int __init wf_pm112_init(void)
+{
+	struct device_node *cpu;
+
+	if (!machine_is_compatible("PowerMac11,2"))
+		return -ENODEV;
+
+	/* Count the number of CPU cores */
+	nr_cores = 0;
+	for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; )
+		++nr_cores;
+
+	printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n");
+	driver_register(&wf_pm112_driver);
+	return 0;
+}
+
+static void __exit wf_pm112_exit(void)
+{
+	driver_unregister(&wf_pm112_driver);
+}
+
+module_init(wf_pm112_init);
+module_exit(wf_pm112_exit);
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("Thermal control for PowerMac11,2");
+MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index eb69a60..f1df6ef 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -538,45 +538,6 @@
 	}
 }
 
-
-/*
- * ****** Attributes ******
- *
- */
-
-#define BUILD_SHOW_FUNC_FIX(name, data)				\
-static ssize_t show_##name(struct device *dev,                  \
-			   struct device_attribute *attr,       \
-			   char *buf)	                        \
-{								\
-	ssize_t r;						\
-	s32 val = 0;                                            \
-	data->ops->get_value(data, &val);                       \
-	r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); 	\
-	return r;						\
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-
-#define BUILD_SHOW_FUNC_INT(name, data)				\
-static ssize_t show_##name(struct device *dev,                  \
-			   struct device_attribute *attr,       \
-			   char *buf)	                        \
-{								\
-	s32 val = 0;                                            \
-	data->ops->get_value(data, &val);                       \
-	return sprintf(buf, "%d", val);  			\
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
-BUILD_SHOW_FUNC_INT(sys_fan, fan_system);
-BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
-
-BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
-BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
-BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
-
 /*
  * ****** Setup / Init / Misc ... ******
  *
@@ -654,17 +615,13 @@
 		return;
 
 	if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) {
-		if (wf_get_control(ct) == 0) {
+		if (wf_get_control(ct) == 0)
 			fan_cpu_main = ct;
-			device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
-		}
 	}
 
 	if (fan_system == NULL && !strcmp(ct->name, "system-fan")) {
-		if (wf_get_control(ct) == 0) {
+		if (wf_get_control(ct) == 0)
 			fan_system = ct;
-			device_create_file(wf_smu_dev, &dev_attr_sys_fan);
-		}
 	}
 
 	if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
@@ -683,10 +640,8 @@
 	}
 
 	if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
-		if (wf_get_control(ct) == 0) {
+		if (wf_get_control(ct) == 0)
 			fan_hd = ct;
-			device_create_file(wf_smu_dev, &dev_attr_hd_fan);
-		}
 	}
 
 	if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp)
@@ -699,24 +654,18 @@
 		return;
 
 	if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
-		if (wf_get_sensor(sr) == 0) {
+		if (wf_get_sensor(sr) == 0)
 			sensor_cpu_power = sr;
-			device_create_file(wf_smu_dev, &dev_attr_cpu_power);
-		}
 	}
 
 	if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
-		if (wf_get_sensor(sr) == 0) {
+		if (wf_get_sensor(sr) == 0)
 			sensor_cpu_temp = sr;
-			device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
-		}
 	}
 
 	if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
-		if (wf_get_sensor(sr) == 0) {
+		if (wf_get_sensor(sr) == 0)
 			sensor_hd_temp = sr;
-			device_create_file(wf_smu_dev, &dev_attr_hd_temp);
-		}
 	}
 
 	if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp)
@@ -794,32 +743,20 @@
 	 * with that except by adding locks all over... I'll do that
 	 * eventually but heh, who ever rmmod this module anyway ?
 	 */
-	if (sensor_cpu_power) {
-		device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+	if (sensor_cpu_power)
 		wf_put_sensor(sensor_cpu_power);
-	}
-	if (sensor_cpu_temp) {
-		device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+	if (sensor_cpu_temp)
 		wf_put_sensor(sensor_cpu_temp);
-	}
-	if (sensor_hd_temp) {
-		device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+	if (sensor_hd_temp)
 		wf_put_sensor(sensor_hd_temp);
-	}
 
 	/* Release all controls */
-	if (fan_cpu_main) {
-		device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+	if (fan_cpu_main)
 		wf_put_control(fan_cpu_main);
-	}
-	if (fan_hd) {
-		device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+	if (fan_hd)
 		wf_put_control(fan_hd);
-	}
-	if (fan_system) {
-		device_remove_file(wf_smu_dev, &dev_attr_sys_fan);
+	if (fan_system)
 		wf_put_control(fan_system);
-	}
 	if (cpufreq_clamp)
 		wf_put_control(cpufreq_clamp);
 
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
index 43243cf..0d6372e 100644
--- a/drivers/macintosh/windfarm_pm91.c
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -458,45 +458,6 @@
 
 
 /*
- * ****** Attributes ******
- *
- */
-
-#define BUILD_SHOW_FUNC_FIX(name, data)				\
-static ssize_t show_##name(struct device *dev,                  \
-			   struct device_attribute *attr,       \
-			   char *buf)	                        \
-{								\
-	ssize_t r;						\
-	s32 val = 0;                                            \
-	data->ops->get_value(data, &val);                       \
-	r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); 	\
-	return r;						\
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-
-#define BUILD_SHOW_FUNC_INT(name, data)				\
-static ssize_t show_##name(struct device *dev,                  \
-			   struct device_attribute *attr,       \
-			   char *buf)	                        \
-{								\
-	s32 val = 0;                                            \
-	data->ops->get_value(data, &val);                       \
-	return sprintf(buf, "%d", val);  			\
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
-BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
-BUILD_SHOW_FUNC_INT(slots_fan, fan_slots);
-
-BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
-BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
-BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
-BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power);
-
-/*
  * ****** Setup / Init / Misc ... ******
  *
  */
@@ -581,10 +542,8 @@
 		return;
 
 	if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) {
-		if (wf_get_control(ct) == 0) {
+		if (wf_get_control(ct) == 0)
 			fan_cpu_main = ct;
-			device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
-		}
 	}
 
 	if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) {
@@ -603,17 +562,13 @@
 	}
 
 	if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
-		if (wf_get_control(ct) == 0) {
+		if (wf_get_control(ct) == 0)
 			fan_hd = ct;
-			device_create_file(wf_smu_dev, &dev_attr_hd_fan);
-		}
 	}
 
 	if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) {
-		if (wf_get_control(ct) == 0) {
+		if (wf_get_control(ct) == 0)
 			fan_slots = ct;
-			device_create_file(wf_smu_dev, &dev_attr_slots_fan);
-		}
 	}
 
 	if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd &&
@@ -627,31 +582,23 @@
 		return;
 
 	if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
-		if (wf_get_sensor(sr) == 0) {
+		if (wf_get_sensor(sr) == 0)
 			sensor_cpu_power = sr;
-			device_create_file(wf_smu_dev, &dev_attr_cpu_power);
-		}
 	}
 
 	if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
-		if (wf_get_sensor(sr) == 0) {
+		if (wf_get_sensor(sr) == 0)
 			sensor_cpu_temp = sr;
-			device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
-		}
 	}
 
 	if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
-		if (wf_get_sensor(sr) == 0) {
+		if (wf_get_sensor(sr) == 0)
 			sensor_hd_temp = sr;
-			device_create_file(wf_smu_dev, &dev_attr_hd_temp);
-		}
 	}
 
 	if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) {
-		if (wf_get_sensor(sr) == 0) {
+		if (wf_get_sensor(sr) == 0)
 			sensor_slots_power = sr;
-			device_create_file(wf_smu_dev, &dev_attr_slots_power);
-		}
 	}
 
 	if (sensor_cpu_power && sensor_cpu_temp &&
@@ -720,40 +667,26 @@
 	 * with that except by adding locks all over... I'll do that
 	 * eventually but heh, who ever rmmod this module anyway ?
 	 */
-	if (sensor_cpu_power) {
-		device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+	if (sensor_cpu_power)
 		wf_put_sensor(sensor_cpu_power);
-	}
-	if (sensor_cpu_temp) {
-		device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+	if (sensor_cpu_temp)
 		wf_put_sensor(sensor_cpu_temp);
-	}
-	if (sensor_hd_temp) {
-		device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+	if (sensor_hd_temp)
 		wf_put_sensor(sensor_hd_temp);
-	}
-	if (sensor_slots_power) {
-		device_remove_file(wf_smu_dev, &dev_attr_slots_power);
+	if (sensor_slots_power)
 		wf_put_sensor(sensor_slots_power);
-	}
 
 	/* Release all controls */
-	if (fan_cpu_main) {
-		device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+	if (fan_cpu_main)
 		wf_put_control(fan_cpu_main);
-	}
 	if (fan_cpu_second)
 		wf_put_control(fan_cpu_second);
 	if (fan_cpu_third)
 		wf_put_control(fan_cpu_third);
-	if (fan_hd) {
-		device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+	if (fan_hd)
 		wf_put_control(fan_hd);
-	}
-	if (fan_slots) {
-		device_remove_file(wf_smu_dev, &dev_attr_slots_fan);
+	if (fan_slots)
 		wf_put_control(fan_slots);
-	}
 	if (cpufreq_clamp)
 		wf_put_control(cpufreq_clamp);
 
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index 4d81160..a9e88ed 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -24,7 +24,7 @@
 
 #include "windfarm.h"
 
-#define VERSION "0.3"
+#define VERSION "0.4"
 
 #undef DEBUG
 
@@ -34,6 +34,8 @@
 #define DBG(args...)	do { } while(0)
 #endif
 
+static int smu_supports_new_fans_ops = 1;
+
 /*
  * SMU fans control object
  */
@@ -59,23 +61,49 @@
 
 	/* Fill SMU command structure */
 	cmd.cmd = SMU_CMD_FAN_COMMAND;
-	cmd.data_len = 14;
+
+	/* The SMU has an "old" and a "new" way of setting the fan speed
+	 * Unfortunately, I found no reliable way to know which one works
+	 * on a given machine model. After some investigations it appears
+	 * that MacOS X just tries the new one, and if it fails fallbacks
+	 * to the old ones ... Ugh.
+	 */
+ retry:
+	if (smu_supports_new_fans_ops) {
+		buffer[0] = 0x30;
+		buffer[1] = id;
+		*((u16 *)(&buffer[2])) = value;
+		cmd.data_len = 4;
+	} else {
+		if (id > 7)
+			return -EINVAL;
+		/* Fill argument buffer */
+		memset(buffer, 0, 16);
+		buffer[0] = pwm ? 0x10 : 0x00;
+		buffer[1] = 0x01 << id;
+		*((u16 *)&buffer[2 + id * 2]) = value;
+		cmd.data_len = 14;
+	}
+
 	cmd.reply_len = 16;
 	cmd.data_buf = cmd.reply_buf = buffer;
 	cmd.status = 0;
 	cmd.done = smu_done_complete;
 	cmd.misc = &comp;
 
-	/* Fill argument buffer */
-	memset(buffer, 0, 16);
-	buffer[0] = pwm ? 0x10 : 0x00;
-	buffer[1] = 0x01 << id;
-	*((u16 *)&buffer[2 + id * 2]) = value;
-
 	rc = smu_queue_cmd(&cmd);
 	if (rc)
 		return rc;
 	wait_for_completion(&comp);
+
+	/* Handle fallback (see coment above) */
+	if (cmd.status != 0 && smu_supports_new_fans_ops) {
+		printk(KERN_WARNING "windfarm: SMU failed new fan command "
+		       "falling back to old method\n");
+		smu_supports_new_fans_ops = 0;
+		goto retry;
+	}
+
 	return cmd.status;
 }
 
@@ -158,19 +186,29 @@
 
 	/* Names used on desktop models */
 	if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") ||
-	    !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan"))
+	    !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") ||
+	    !strcmp(l, "CPU A EXHAUST"))
 		fct->ctrl.name = "cpu-rear-fan-0";
-	else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1"))
+	else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") ||
+		 !strcmp(l, "CPU B EXHAUST"))
 		fct->ctrl.name = "cpu-rear-fan-1";
 	else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") ||
-		 !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan"))
+		 !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") ||
+		 !strcmp(l, "CPU A INTAKE"))
 		fct->ctrl.name = "cpu-front-fan-0";
-	else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1"))
+	else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") ||
+		 !strcmp(l, "CPU B INTAKE"))
 		fct->ctrl.name = "cpu-front-fan-1";
-	else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan"))
+	else if (!strcmp(l, "CPU A PUMP"))
+		fct->ctrl.name = "cpu-pump-0";
+	else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") ||
+		 !strcmp(l, "EXPANSION SLOTS INTAKE"))
 		fct->ctrl.name = "slots-fan";
-	else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay"))
+	else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") ||
+		 !strcmp(l, "DRIVE BAY A INTAKE"))
 		fct->ctrl.name = "drive-bay-fan";
+	else if (!strcmp(l, "BACKSIDE"))
+		fct->ctrl.name = "backside-fan";
 
 	/* Names used on iMac models */
 	if (!strcmp(l, "System Fan") || !strcmp(l, "System fan"))
@@ -223,7 +261,8 @@
 
 	/* Look for RPM fans */
 	for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
-		if (!strcmp(fans->name, "rpm-fans"))
+		if (!strcmp(fans->name, "rpm-fans") ||
+		    device_is_compatible(fans, "smu-rpm-fans"))
 			break;
 	for (fan = NULL;
 	     fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
new file mode 100644
index 0000000..3a32c59
--- /dev/null
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -0,0 +1,418 @@
+/*
+ * Windfarm PowerMac thermal control.  SMU "satellite" controller sensors.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ *
+ * Released under the terms of the GNU GPL v2.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/semaphore.h>
+#include <asm/prom.h>
+#include <asm/smu.h>
+#include <asm/pmac_low_i2c.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.2"
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG(args...)	printk(args)
+#else
+#define DBG(args...)	do { } while(0)
+#endif
+
+/* If the cache is older than 800ms we'll refetch it */
+#define MAX_AGE		msecs_to_jiffies(800)
+
+struct wf_sat {
+	int			nr;
+	atomic_t		refcnt;
+	struct semaphore	mutex;
+	unsigned long		last_read; /* jiffies when cache last updated */
+	u8			cache[16];
+	struct i2c_client	i2c;
+	struct device_node	*node;
+};
+
+static struct wf_sat *sats[2];
+
+struct wf_sat_sensor {
+	int		index;
+	int		index2;		/* used for power sensors */
+	int		shift;
+	struct wf_sat	*sat;
+	struct wf_sensor sens;
+};
+
+#define wf_to_sat(c)	container_of(c, struct wf_sat_sensor, sens)
+#define i2c_to_sat(c)	container_of(c, struct wf_sat, i2c)
+
+static int wf_sat_attach(struct i2c_adapter *adapter);
+static int wf_sat_detach(struct i2c_client *client);
+
+static struct i2c_driver wf_sat_driver = {
+	.driver = {
+		.name		= "wf_smu_sat",
+	},
+	.attach_adapter	= wf_sat_attach,
+	.detach_client	= wf_sat_detach,
+};
+
+/*
+ * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested
+ * length down to the low-level driver, so we use this, which
+ * works well enough with the SMU i2c driver code...
+ */
+static int sat_read_block(struct i2c_client *client, u8 command,
+			  u8 *values, int len)
+{
+	union i2c_smbus_data data;
+	int err;
+
+	data.block[0] = len;
+	err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+			     I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA,
+			     &data);
+	if (!err)
+		memcpy(values, data.block, len);
+	return err;
+}
+
+struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
+						  unsigned int *size)
+{
+	struct wf_sat *sat;
+	int err;
+	unsigned int i, len;
+	u8 *buf;
+	u8 data[4];
+
+	/* TODO: Add the resulting partition to the device-tree */
+
+	if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
+		return NULL;
+
+	err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8);
+	if (err) {
+		printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
+		return NULL;
+	}
+
+	len = i2c_smbus_read_word_data(&sat->i2c, 9);
+	if (len < 0) {
+		printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
+		return NULL;
+	}
+	if (len == 0) {
+		printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id);
+		return NULL;
+	}
+
+	len = le16_to_cpu(len);
+	len = (len + 3) & ~3;
+	buf = kmalloc(len, GFP_KERNEL);
+	if (buf == NULL)
+		return NULL;
+
+	for (i = 0; i < len; i += 4) {
+		err = sat_read_block(&sat->i2c, 0xa, data, 4);
+		if (err) {
+			printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
+			       err);
+			goto fail;
+		}
+		buf[i] = data[1];
+		buf[i+1] = data[0];
+		buf[i+2] = data[3];
+		buf[i+3] = data[2];
+	}
+#ifdef DEBUG
+	DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id);
+	for (i = 0; i < len; ++i)
+		DBG(" %x", buf[i]);
+	DBG("\n");
+#endif
+
+	if (size)
+		*size = len;
+	return (struct smu_sdbp_header *) buf;
+
+ fail:
+	kfree(buf);
+	return NULL;
+}
+
+/* refresh the cache */
+static int wf_sat_read_cache(struct wf_sat *sat)
+{
+	int err;
+
+	err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16);
+	if (err)
+		return err;
+	sat->last_read = jiffies;
+#ifdef LOTSA_DEBUG
+	{
+		int i;
+		DBG(KERN_DEBUG "wf_sat_get: data is");
+		for (i = 0; i < 16; ++i)
+			DBG(" %.2x", sat->cache[i]);
+		DBG("\n");
+	}
+#endif
+	return 0;
+}
+
+static int wf_sat_get(struct wf_sensor *sr, s32 *value)
+{
+	struct wf_sat_sensor *sens = wf_to_sat(sr);
+	struct wf_sat *sat = sens->sat;
+	int i, err;
+	s32 val;
+
+	if (sat->i2c.adapter == NULL)
+		return -ENODEV;
+
+	down(&sat->mutex);
+	if (time_after(jiffies, (sat->last_read + MAX_AGE))) {
+		err = wf_sat_read_cache(sat);
+		if (err)
+			goto fail;
+	}
+
+	i = sens->index * 2;
+	val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift;
+	if (sens->index2 >= 0) {
+		i = sens->index2 * 2;
+		/* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */
+		val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4;
+	}
+
+	*value = val;
+	err = 0;
+
+ fail:
+	up(&sat->mutex);
+	return err;
+}
+
+static void wf_sat_release(struct wf_sensor *sr)
+{
+	struct wf_sat_sensor *sens = wf_to_sat(sr);
+	struct wf_sat *sat = sens->sat;
+
+	if (atomic_dec_and_test(&sat->refcnt)) {
+		if (sat->i2c.adapter) {
+			i2c_detach_client(&sat->i2c);
+			sat->i2c.adapter = NULL;
+		}
+		if (sat->nr >= 0)
+			sats[sat->nr] = NULL;
+		kfree(sat);
+	}
+	kfree(sens);
+}
+
+static struct wf_sensor_ops wf_sat_ops = {
+	.get_value	= wf_sat_get,
+	.release	= wf_sat_release,
+	.owner		= THIS_MODULE,
+};
+
+static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
+{
+	struct wf_sat *sat;
+	struct wf_sat_sensor *sens;
+	u32 *reg;
+	char *loc, *type;
+	u8 addr, chip, core;
+	struct device_node *child;
+	int shift, cpu, index;
+	char *name;
+	int vsens[2], isens[2];
+
+	reg = (u32 *) get_property(dev, "reg", NULL);
+	if (reg == NULL)
+		return;
+	addr = *reg;
+	DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
+
+	sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
+	if (sat == NULL)
+		return;
+	sat->nr = -1;
+	sat->node = of_node_get(dev);
+	atomic_set(&sat->refcnt, 0);
+	init_MUTEX(&sat->mutex);
+	sat->i2c.addr = (addr >> 1) & 0x7f;
+	sat->i2c.adapter = adapter;
+	sat->i2c.driver = &wf_sat_driver;
+	strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1);
+
+	if (i2c_attach_client(&sat->i2c)) {
+		printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
+		goto fail;
+	}
+
+	vsens[0] = vsens[1] = -1;
+	isens[0] = isens[1] = -1;
+	child = NULL;
+	while ((child = of_get_next_child(dev, child)) != NULL) {
+		reg = (u32 *) get_property(child, "reg", NULL);
+		type = get_property(child, "device_type", NULL);
+		loc = get_property(child, "location", NULL);
+		if (reg == NULL || loc == NULL)
+			continue;
+
+		/* the cooked sensors are between 0x30 and 0x37 */
+		if (*reg < 0x30 || *reg > 0x37)
+			continue;
+		index = *reg - 0x30;
+
+		/* expect location to be CPU [AB][01] ... */
+		if (strncmp(loc, "CPU ", 4) != 0)
+			continue;
+		chip = loc[4] - 'A';
+		core = loc[5] - '0';
+		if (chip > 1 || core > 1) {
+			printk(KERN_ERR "wf_sat_create: don't understand "
+			       "location %s for %s\n", loc, child->full_name);
+			continue;
+		}
+		cpu = 2 * chip + core;
+		if (sat->nr < 0)
+			sat->nr = chip;
+		else if (sat->nr != chip) {
+			printk(KERN_ERR "wf_sat_create: can't cope with "
+			       "multiple CPU chips on one SAT (%s)\n", loc);
+			continue;
+		}
+
+		if (strcmp(type, "voltage-sensor") == 0) {
+			name = "cpu-voltage";
+			shift = 4;
+			vsens[core] = index;
+		} else if (strcmp(type, "current-sensor") == 0) {
+			name = "cpu-current";
+			shift = 8;
+			isens[core] = index;
+		} else if (strcmp(type, "temp-sensor") == 0) {
+			name = "cpu-temp";
+			shift = 10;
+		} else
+			continue;	/* hmmm shouldn't happen */
+
+		/* the +16 is enough for "cpu-voltage-n" */
+		sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
+		if (sens == NULL) {
+			printk(KERN_ERR "wf_sat_create: couldn't create "
+			       "%s sensor %d (no memory)\n", name, cpu);
+			continue;
+		}
+		sens->index = index;
+		sens->index2 = -1;
+		sens->shift = shift;
+		sens->sat = sat;
+		atomic_inc(&sat->refcnt);
+		sens->sens.ops = &wf_sat_ops;
+		sens->sens.name = (char *) (sens + 1);
+		snprintf(sens->sens.name, 16, "%s-%d", name, cpu);
+
+		if (wf_register_sensor(&sens->sens)) {
+			atomic_dec(&sat->refcnt);
+			kfree(sens);
+		}
+	}
+
+	/* make the power sensors */
+	for (core = 0; core < 2; ++core) {
+		if (vsens[core] < 0 || isens[core] < 0)
+			continue;
+		cpu = 2 * sat->nr + core;
+		sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
+		if (sens == NULL) {
+			printk(KERN_ERR "wf_sat_create: couldn't create power "
+			       "sensor %d (no memory)\n", cpu);
+			continue;
+		}
+		sens->index = vsens[core];
+		sens->index2 = isens[core];
+		sens->shift = 0;
+		sens->sat = sat;
+		atomic_inc(&sat->refcnt);
+		sens->sens.ops = &wf_sat_ops;
+		sens->sens.name = (char *) (sens + 1);
+		snprintf(sens->sens.name, 16, "cpu-power-%d", cpu);
+
+		if (wf_register_sensor(&sens->sens)) {
+			atomic_dec(&sat->refcnt);
+			kfree(sens);
+		}
+	}
+
+	if (sat->nr >= 0)
+		sats[sat->nr] = sat;
+
+	return;
+
+ fail:
+	kfree(sat);
+}
+
+static int wf_sat_attach(struct i2c_adapter *adapter)
+{
+	struct device_node *busnode, *dev = NULL;
+	struct pmac_i2c_bus *bus;
+
+	bus = pmac_i2c_adapter_to_bus(adapter);
+	if (bus == NULL)
+		return -ENODEV;
+	busnode = pmac_i2c_get_bus_node(bus);
+
+	while ((dev = of_get_next_child(busnode, dev)) != NULL)
+		if (device_is_compatible(dev, "smu-sat"))
+			wf_sat_create(adapter, dev);
+	return 0;
+}
+
+static int wf_sat_detach(struct i2c_client *client)
+{
+	struct wf_sat *sat = i2c_to_sat(client);
+
+	/* XXX TODO */
+
+	sat->i2c.adapter = NULL;
+	return 0;
+}
+
+static int __init sat_sensors_init(void)
+{
+	int err;
+
+	err = i2c_add_driver(&wf_sat_driver);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+static void __exit sat_sensors_exit(void)
+{
+	i2c_del_driver(&wf_sat_driver);
+}
+
+module_init(sat_sensors_init);
+/*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control");
+MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
index 1a00d9c..bed25dc 100644
--- a/drivers/macintosh/windfarm_smu_sensors.c
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -220,14 +220,29 @@
 	    !strcmp(l, "CPU T-Diode")) {
 		ads->sens.ops = &smu_cputemp_ops;
 		ads->sens.name = "cpu-temp";
+		if (cpudiode == NULL) {
+			DBG("wf: cpudiode partition (%02x) not found\n",
+			    SMU_SDB_CPUDIODE_ID);
+			goto fail;
+		}
 	} else if (!strcmp(c, "current-sensor") &&
 		   !strcmp(l, "CPU Current")) {
 		ads->sens.ops = &smu_cpuamp_ops;
 		ads->sens.name = "cpu-current";
+		if (cpuvcp == NULL) {
+			DBG("wf: cpuvcp partition (%02x) not found\n",
+			    SMU_SDB_CPUVCP_ID);
+			goto fail;
+		}
 	} else if (!strcmp(c, "voltage-sensor") &&
 		   !strcmp(l, "CPU Voltage")) {
 		ads->sens.ops = &smu_cpuvolt_ops;
 		ads->sens.name = "cpu-voltage";
+		if (cpuvcp == NULL) {
+			DBG("wf: cpuvcp partition (%02x) not found\n",
+			    SMU_SDB_CPUVCP_ID);
+			goto fail;
+		}
 	} else if (!strcmp(c, "power-sensor") &&
 		   !strcmp(l, "Slots Power")) {
 		ads->sens.ops = &smu_slotspow_ops;
@@ -365,29 +380,22 @@
 	return NULL;
 }
 
-static int smu_fetch_param_partitions(void)
+static void smu_fetch_param_partitions(void)
 {
 	struct smu_sdbp_header *hdr;
 
 	/* Get CPU voltage/current/power calibration data */
 	hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL);
-	if (hdr == NULL) {
-		DBG("wf: cpuvcp partition (%02x) not found\n",
-		    SMU_SDB_CPUVCP_ID);
-		return -ENODEV;
+	if (hdr != NULL) {
+		cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
+		/* Keep version around */
+		cpuvcp_version = hdr->version;
 	}
-	cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
-	/* Keep version around */
-	cpuvcp_version = hdr->version;
 
 	/* Get CPU diode calibration data */
 	hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL);
-	if (hdr == NULL) {
-		DBG("wf: cpudiode partition (%02x) not found\n",
-		    SMU_SDB_CPUDIODE_ID);
-		return -ENODEV;
-	}
-	cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
+	if (hdr != NULL)
+		cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
 
 	/* Get slots power calibration data if any */
 	hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL);
@@ -398,23 +406,18 @@
 	hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL);
 	if (hdr != NULL)
 		debugswitches = (u8 *)&hdr[1];
-
-	return 0;
 }
 
 static int __init smu_sensors_init(void)
 {
 	struct device_node *smu, *sensors, *s;
 	struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL;
-	int rc;
 
 	if (!smu_present())
 		return -ENODEV;
 
 	/* Get parameters partitions */
-	rc = smu_fetch_param_partitions();
-	if (rc)
-		return rc;
+	smu_fetch_param_partitions();
 
 	smu = of_find_node_by_type(NULL, "smu");
 	if (smu == NULL)
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 2583a86..2963605 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -4,7 +4,7 @@
 	select DVB_STV0299
 	select DVB_MT352
 	select DVB_MT312
-	select DVB_NXT2002
+	select DVB_NXT200X
 	select DVB_STV0297
 	select DVB_BCM3510
 	select DVB_LGDT330X
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 344a3c8..7d7e161 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -116,11 +116,9 @@
 
 int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
 int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
 int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
-int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
 
 /* from flexcop-eeprom.c */
 /* the PCI part uses this call to get the MAC address, the USB part has its own */
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index cf4ed1d..6f592bc 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -169,38 +169,3 @@
 }
 EXPORT_SYMBOL(flexcop_dma_config_timer);
 
-/* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc,
-		flexcop_dma_index_t no,
-		int onoff)
-{
-	flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
-
-	deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
-	if (no & FC_DMA_1)
-		v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
-
-	if (no & FC_DMA_2)
-		v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
-
-	fc->write_ibi_reg(fc,ctrl_208,v);
-	deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
-
-	return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
-
-int flexcop_dma_config_packet_count(struct flexcop_device *fc,
-		flexcop_dma_index_t dma_idx,
-		u8 packets)
-{
-	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
-	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
-
-	flexcop_dma_remap(fc,dma_idx,1);
-
-	v.dma_0x4_remap.DMA_maxpackets = packets;
-	fc->write_ibi_reg(fc,r,v);
-	return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config_packet_count);
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 0b940e1..390cc3a 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -9,7 +9,7 @@
 
 #include "stv0299.h"
 #include "mt352.h"
-#include "nxt2002.h"
+#include "nxt200x.h"
 #include "bcm3510.h"
 #include "stv0297.h"
 #include "mt312.h"
@@ -343,9 +343,10 @@
 	.clock_polarity_flip = 1,
 };
 
-static struct nxt2002_config samsung_tbmv_config = {
+static struct nxt200x_config samsung_tbmv_config = {
 	.demod_address    = 0x0a,
-	.request_firmware = flexcop_fe_request_firmware,
+	.pll_address      = 0xc2,
+	.pll_desc         = &dvb_pll_samsung_tbmv,
 };
 
 static struct bcm3510_config air2pc_atsc_first_gen_config = {
@@ -505,7 +506,7 @@
 		info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
 	} else
 	/* try the air atsc 2nd generation (nxt2002) */
-	if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
+	if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
 		fc->dev_type          = FC_AIR_ATSC2;
 		info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
 	} else
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 62282d8..167583b 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -36,14 +36,14 @@
 	/* bus parts have to decide if hw pid filtering is used or not. */
 }
 
-const char *flexcop_revision_names[] = {
+static const char *flexcop_revision_names[] = {
 	"Unkown chip",
 	"FlexCopII",
 	"FlexCopIIb",
 	"FlexCopIII",
 };
 
-const char *flexcop_device_names[] = {
+static const char *flexcop_device_names[] = {
 	"Unkown device",
 	"Air2PC/AirStar 2 DVB-T",
 	"Air2PC/AirStar 2 ATSC 1st generation",
@@ -54,7 +54,7 @@
 	"Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
 };
 
-const char *flexcop_bus_names[] = {
+static const char *flexcop_bus_names[] = {
 	"USB",
 	"PCI",
 };
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 2f76eb3..9bc40bd 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -161,8 +161,10 @@
 			fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
 		u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
 
-		deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
-				jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+		deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
+				jiffies_to_usecs(jiffies - fc_pci->last_irq),
+				v.raw, (unsigned long long)cur_addr, cur_pos,
+				fc_pci->last_dma1_cur_pos);
 		fc_pci->last_irq = jiffies;
 
 		/* buffer end was reached, restarted from the beginning
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 3153f95..491f9bd 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -16,8 +16,6 @@
 	FLEXCOP_III,
 } flexcop_revision_t;
 
-extern const char *flexcop_revision_names[];
-
 typedef enum {
 	FC_UNK = 0,
 	FC_AIR_DVB,
@@ -34,8 +32,6 @@
 	FC_PCI,
 } flexcop_bus_t;
 
-extern const char *flexcop_device_names[];
-
 /* FlexCop IBI Registers */
 #if defined(__LITTLE_ENDIAN)
 	#include "flexcop_ibi_value_le.h"
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index a04bb61..34c3189 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -381,6 +381,23 @@
 
 EXPORT_SYMBOL(bt878_device_control);
 
+
+struct cards card_list[] __devinitdata = {
+
+	{ 0x01010071, BTTV_BOARD_NEBULA_DIGITV,			"Nebula Electronics DigiTV" },
+	{ 0x07611461, BTTV_BOARD_AVDVBT_761,			"AverMedia AverTV DVB-T 761" },
+	{ 0x001c11bd, BTTV_BOARD_PINNACLESAT,			"Pinnacle PCTV Sat" },
+	{ 0x002611bd, BTTV_BOARD_TWINHAN_DST,			"Pinnacle PCTV SAT CI" },
+	{ 0x00011822, BTTV_BOARD_TWINHAN_DST,			"Twinhan VisionPlus DVB" },
+	{ 0xfc00270f, BTTV_BOARD_TWINHAN_DST,			"ChainTech digitop DST-1000 DVB-S" },
+	{ 0x07711461, BTTV_BOARD_AVDVBT_771,			"AVermedia AverTV DVB-T 771" },
+	{ 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE,		"DViCO FusionHDTV DVB-T Lite" },
+	{ 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE,	"DViCO FusionHDTV 5 Lite" },
+	{ 0x20007063, BTTV_BOARD_PC_HDTV,			"pcHDTV HD-2000 TV"},
+	{ 0, -1, NULL }
+};
+
+
 /***********************/
 /* PCI device handling */
 /***********************/
@@ -388,18 +405,41 @@
 static int __devinit bt878_probe(struct pci_dev *dev,
 				 const struct pci_device_id *pci_id)
 {
-	int result;
+	int result = 0, has_dvb = 0, i;
 	unsigned char lat;
 	struct bt878 *bt;
 #if defined(__powerpc__)
 	unsigned int cmd;
 #endif
+	unsigned int cardid;
+	unsigned short id;
+	struct cards *dvb_cards;
 
 	printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
 	       bt878_num);
 	if (pci_enable_device(dev))
 		return -EIO;
 
+	pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id);
+	cardid = id << 16;
+	pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id);
+	cardid |= id;
+
+	for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) {
+		if (cardid == dvb_cards->pci_id) {
+			printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n",
+				__func__, cardid, dvb_cards->name);
+			has_dvb = 1;
+		}
+	}
+
+	if (!has_dvb) {
+		printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid);
+		result = -EINVAL;
+
+		goto fail0;
+	}
+
 	bt = &bt878[bt878_num];
 	bt->dev = dev;
 	bt->nr = bt878_num;
@@ -416,6 +456,8 @@
 
 	pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+
+
 	printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
 	       bt878_num, bt->id, bt->revision, dev->bus->number,
 	       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index a73baf0..9faf937 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -88,6 +88,23 @@
 
 #define BT878_RISC_SYNC_MASK	(1 << 15)
 
+
+#define BTTV_BOARD_UNKNOWN                 0x00
+#define BTTV_BOARD_PINNACLESAT             0x5e
+#define BTTV_BOARD_NEBULA_DIGITV           0x68
+#define BTTV_BOARD_PC_HDTV                 0x70
+#define BTTV_BOARD_TWINHAN_DST             0x71
+#define BTTV_BOARD_AVDVBT_771              0x7b
+#define BTTV_BOARD_AVDVBT_761              0x7c
+#define BTTV_BOARD_DVICO_DVBT_LITE         0x80
+#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
+
+struct cards {
+	__u32 pci_id;
+	__u16 card_id;
+	char  *name;
+};
+
 extern int bt878_num;
 
 struct bt878 {
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 90a69d3..d3df120 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -83,12 +83,18 @@
 	  Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
 
 config DVB_USB_CXUSB
-	tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
+	tristate "Conexant USB2.0 hybrid reference design support"
 	depends on DVB_USB
 	select DVB_CX22702
+	select DVB_LGDT330X
+	select DVB_MT352
 	help
-	  Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
-	  only the DVB-T part is supported.
+	  Say Y here to support the Conexant USB2.0 hybrid reference design.
+	  Currently, only DVB and ATSC modes are supported, analog mode
+	  shall be added in the future. Devices that require this module:
+
+	  Medion MD95700 hybrid USB2.0 device.
+	  DViCO FusionHDTV (Bluebird) USB2.0 devices
 
 config DVB_USB_DIGITV
 	tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index a7fb06f..f327fac 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -184,7 +184,7 @@
 	return 0;
 }
 
-struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
+static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
 	{ 0xfe, 0x02, KEY_TV },
 	{ 0xfe, 0x0e, KEY_MP3 },
 	{ 0xfe, 0x1a, KEY_DVD },
@@ -234,7 +234,7 @@
 
 static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
 {
-	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
+	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
 	static u8 reset []         = { RESET,      0x80 };
 	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
 	static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
@@ -255,7 +255,7 @@
 
 static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
 {	/* used in both lgz201 and th7579 */
-	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
+	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x29 };
 	static u8 reset []         = { RESET,      0x80 };
 	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
 	static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
@@ -273,7 +273,7 @@
 	return 0;
 }
 
-struct cx22702_config cxusb_cx22702_config = {
+static struct cx22702_config cxusb_cx22702_config = {
 	.demod_address = 0x63,
 
 	.output_mode = CX22702_PARALLEL_OUTPUT,
@@ -282,13 +282,13 @@
 	.pll_set  = dvb_usb_pll_set_i2c,
 };
 
-struct lgdt330x_config cxusb_lgdt330x_config = {
+static struct lgdt330x_config cxusb_lgdt330x_config = {
 	.demod_address = 0x0e,
 	.demod_chip    = LGDT3303,
 	.pll_set       = dvb_usb_pll_set_i2c,
 };
 
-struct mt352_config cxusb_dee1601_config = {
+static struct mt352_config cxusb_dee1601_config = {
 	.demod_address = 0x0f,
 	.demod_init    = cxusb_dee1601_demod_init,
 	.pll_set       = dvb_usb_pll_set,
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index e6c55c9..caa1346 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -175,11 +175,13 @@
 	if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
 		u8 b[4] = { 0 };
 
-		b[0] = 1;
-		digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
+		if (d != NULL) { /* do that only when the firmware is loaded */
+			b[0] = 1;
+			digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
 
-		b[0] = 0;
-		digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+			b[0] = 0;
+			digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+		}
 	}
 	return ret;
 }
@@ -194,7 +196,7 @@
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
-	.firmware = "dvb-usb-digitv-01.fw",
+	.firmware = "dvb-usb-digitv-02.fw",
 
 	.size_of_priv     = 0,
 
@@ -229,6 +231,7 @@
 			{ &digitv_table[0], NULL },
 			{ NULL },
 		},
+		{ NULL },
 	}
 };
 
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 130ea7f..12ebaf8 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -151,7 +151,7 @@
 		  .cold_ids = { &dtt200u_usb_table[0], NULL },
 		  .warm_ids = { &dtt200u_usb_table[1], NULL },
 		},
-		{ 0 },
+		{ NULL },
 	}
 };
 
@@ -192,7 +192,7 @@
 		  .cold_ids = { &dtt200u_usb_table[2], NULL },
 		  .warm_ids = { &dtt200u_usb_table[3], NULL },
 		},
-		{ 0 },
+		{ NULL },
 	}
 };
 
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
index 8535895..9222b0a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -24,6 +24,9 @@
 	{ .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
 };
 
+static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+			       int *pos);
+
 /*
  * load a firmware packet to the device
  */
@@ -112,7 +115,8 @@
 	return ret;
 }
 
-int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos)
+static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+			       int *pos)
 {
 	u8 *b = (u8 *) &fw->data[*pos];
 	int data_offs = 4;
@@ -142,5 +146,3 @@
 
 	return *pos;
 }
-EXPORT_SYMBOL(dvb_usb_get_hexline);
-
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index dd56839..5e5d21a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -341,7 +341,6 @@
 	u8 data[255];
 	u8 chk;
 };
-extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *);
 extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index afa00fd..4a95eca 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -53,7 +53,8 @@
 	return ret;
 }
 
-int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+			     u16 index, u8 *b, int blen)
 {
 	deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
 	debug_dump(b,blen,deb_xfer);
@@ -88,7 +89,8 @@
 	return ret;
 }
 
-int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec)
+static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
+				int olen, u8 *i, int ilen, int msec)
 {
 	u8 bout[olen+2];
 	u8 bin[ilen+1];
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
index a808d48..c2f97f9 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.h
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -101,8 +101,6 @@
 extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
 
 extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
-extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec);
 extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
index 5242cca..9999336 100644
--- a/drivers/media/dvb/dvb-usb/vp7045-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -23,10 +23,11 @@
 
 struct vp7045_fe_state {
 	struct dvb_frontend fe;
+	struct dvb_frontend_ops ops;
+
 	struct dvb_usb_device *d;
 };
 
-
 static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
 {
 	struct vp7045_fe_state *state = fe->demodulator_priv;
@@ -150,7 +151,8 @@
 		goto error;
 
 	s->d = d;
-	s->fe.ops = &vp7045_fe_ops;
+	memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
+	s->fe.ops = &s->ops;
 	s->fe.demodulator_priv = s;
 
 	goto success;
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 0282049..3835235 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -247,7 +247,7 @@
 		  .cold_ids = { &vp7045_usb_table[2], NULL },
 		  .warm_ids = { &vp7045_usb_table[3], NULL },
 		},
-		{ 0 },
+		{ NULL },
 	}
 };
 
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index db3a8b4..76b6a2a 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -28,12 +28,6 @@
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
-config DVB_TDA80XX
-	tristate "Philips TDA8044 or TDA8083 based"
-	depends on DVB_CORE
-	help
-	  A DVB-S tuner module. Say Y when you want to support this frontend.
-
 config DVB_MT312
 	tristate "Zarlink MT312 based"
 	depends on DVB_CORE
@@ -139,12 +133,6 @@
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
-config DVB_ATMEL_AT76C651
-	tristate "Atmel AT76C651 based"
-	depends on DVB_CORE
-	help
-	  A DVB-C tuner module. Say Y when you want to support this frontend.
-
 config DVB_VES1820
 	tristate "VLSI VES1820 based"
 	depends on DVB_CORE
@@ -166,18 +154,6 @@
 comment "ATSC (North American/Korean Terresterial DTV) frontends"
 	depends on DVB_CORE
 
-config DVB_NXT2002
-	tristate "Nxt2002 based"
-	depends on DVB_CORE
-	select FW_LOADER
-	help
-	  An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
-
-	  This driver needs external firmware. Please use the command
-	  "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
-	  download/extract it, and then copy it to /usr/lib/hotplug/firmware
-	  or /lib/firmware (depending on configuration of firmware hotplug).
-
 config DVB_NXT200X
 	tristate "Nextwave NXT2002/NXT2004 based"
 	depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 615ec83..1af769c 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -8,7 +8,6 @@
 obj-$(CONFIG_DVB_STV0299) += stv0299.o
 obj-$(CONFIG_DVB_SP8870) += sp8870.o
 obj-$(CONFIG_DVB_CX22700) += cx22700.o
-obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
 obj-$(CONFIG_DVB_CX24110) += cx24110.o
 obj-$(CONFIG_DVB_TDA8083) += tda8083.o
 obj-$(CONFIG_DVB_L64781) += l64781.o
@@ -22,10 +21,8 @@
 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
-obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
-obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
 obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
 obj-$(CONFIG_DVB_OR51211) += or51211.o
 obj-$(CONFIG_DVB_OR51132) += or51132.o
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
deleted file mode 100644
index 8e0f4b3..0000000
--- a/drivers/media/dvb/frontends/at76c651.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * at76c651.c
- *
- * Atmel DVB-C Frontend Driver (at76c651/tua6010xs)
- *
- * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
- *             & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *             & 2003 Wolfram Joost <dbox2@frokaschwei.de>
- *
- * 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.
- *
- * AT76C651
- * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
- * http://www.atmel.com/atmel/acrobat/doc1320.pdf
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include "dvb_frontend.h"
-#include "at76c651.h"
-
-
-struct at76c651_state {
-
-	struct i2c_adapter* i2c;
-
-	struct dvb_frontend_ops ops;
-
-	const struct at76c651_config* config;
-
-	struct dvb_frontend frontend;
-
-	/* revision of the chip */
-	u8 revision;
-
-	/* last QAM value set */
-	u8 qam;
-};
-
-static int debug;
-#define dprintk(args...) \
-	do { \
-		if (debug) printk(KERN_DEBUG "at76c651: " args); \
-	} while (0)
-
-
-#if ! defined(__powerpc__)
-static __inline__ int __ilog2(unsigned long x)
-{
-	int i;
-
-	if (x == 0)
-		return -1;
-
-	for (i = 0; x != 0; i++)
-		x >>= 1;
-
-	return i - 1;
-}
-#endif
-
-static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data)
-{
-	int ret;
-	u8 buf[] = { reg, data };
-	struct i2c_msg msg =
-		{ .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-
-	ret = i2c_transfer(state->i2c, &msg, 1);
-
-	if (ret != 1)
-		dprintk("%s: writereg error "
-			"(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-			__FUNCTION__, reg, data, ret);
-
-	msleep(10);
-
-	return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static u8 at76c651_readreg(struct at76c651_state* state, u8 reg)
-{
-	int ret;
-	u8 val;
-	struct i2c_msg msg[] = {
-		{ .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
-		{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }
-	};
-
-	ret = i2c_transfer(state->i2c, msg, 2);
-
-	if (ret != 2)
-		dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
-
-	return val;
-}
-
-static int at76c651_reset(struct at76c651_state* state)
-{
-	return at76c651_writereg(state, 0x07, 0x01);
-}
-
-static void at76c651_disable_interrupts(struct at76c651_state* state)
-{
-	at76c651_writereg(state, 0x0b, 0x00);
-}
-
-static int at76c651_set_auto_config(struct at76c651_state *state)
-{
-	/*
-	 * Autoconfig
-	 */
-
-	at76c651_writereg(state, 0x06, 0x01);
-
-	/*
-	 * Performance optimizations, should be done after autoconfig
-	 */
-
-	at76c651_writereg(state, 0x10, 0x06);
-	at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10);
-	at76c651_writereg(state, 0x15, 0x28);
-	at76c651_writereg(state, 0x20, 0x09);
-	at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90);
-	at76c651_writereg(state, 0x30, 0x90);
-	if (state->qam == 5)
-		at76c651_writereg(state, 0x35, 0x2A);
-
-	/*
-	 * Initialize A/D-converter
-	 */
-
-	if (state->revision == 0x11) {
-		at76c651_writereg(state, 0x2E, 0x38);
-		at76c651_writereg(state, 0x2F, 0x13);
-	}
-
-	at76c651_disable_interrupts(state);
-
-	/*
-	 * Restart operation
-	 */
-
-	at76c651_reset(state);
-
-	return 0;
-}
-
-static void at76c651_set_bbfreq(struct at76c651_state* state)
-{
-	at76c651_writereg(state, 0x04, 0x3f);
-	at76c651_writereg(state, 0x05, 0xee);
-}
-
-static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate)
-{
-	u8 exponent;
-	u32 mantissa;
-
-	if (symbol_rate > 9360000)
-		return -EINVAL;
-
-	/*
-	 * FREF = 57800 kHz
-	 * exponent = 10 + floor (log2(symbol_rate / FREF))
-	 * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent))
-	 */
-
-	exponent = __ilog2((symbol_rate << 4) / 903125);
-	mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289;
-
-	at76c651_writereg(state, 0x00, mantissa >> 13);
-	at76c651_writereg(state, 0x01, mantissa >> 5);
-	at76c651_writereg(state, 0x02, (mantissa << 3) | exponent);
-
-	return 0;
-}
-
-static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam)
-{
-	switch (qam) {
-	case QPSK:
-		state->qam = 0x02;
-		break;
-	case QAM_16:
-		state->qam = 0x04;
-		break;
-	case QAM_32:
-		state->qam = 0x05;
-		break;
-	case QAM_64:
-		state->qam = 0x06;
-		break;
-	case QAM_128:
-		state->qam = 0x07;
-		break;
-	case QAM_256:
-		state->qam = 0x08;
-		break;
-#if 0
-	case QAM_512:
-		state->qam = 0x09;
-		break;
-	case QAM_1024:
-		state->qam = 0x0A;
-		break;
-#endif
-	default:
-		return -EINVAL;
-
-	}
-
-	return at76c651_writereg(state, 0x03, state->qam);
-}
-
-static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion)
-{
-	u8 feciqinv = at76c651_readreg(state, 0x60);
-
-	switch (inversion) {
-	case INVERSION_OFF:
-		feciqinv |= 0x02;
-		feciqinv &= 0xFE;
-		break;
-
-	case INVERSION_ON:
-		feciqinv |= 0x03;
-		break;
-
-	case INVERSION_AUTO:
-		feciqinv &= 0xFC;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return at76c651_writereg(state, 0x60, feciqinv);
-}
-
-static int at76c651_set_parameters(struct dvb_frontend* fe,
-				   struct dvb_frontend_parameters *p)
-{
-	int ret;
-	struct at76c651_state* state = fe->demodulator_priv;
-
-	at76c651_writereg(state, 0x0c, 0xc3);
-	state->config->pll_set(fe, p);
-	at76c651_writereg(state, 0x0c, 0xc2);
-
-	if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate)))
-		return ret;
-
-	if ((ret = at76c651_set_inversion(state, p->inversion)))
-		return ret;
-
-	return at76c651_set_auto_config(state);
-}
-
-static int at76c651_set_defaults(struct dvb_frontend* fe)
-{
-	struct at76c651_state* state = fe->demodulator_priv;
-
-	at76c651_set_symbol_rate(state, 6900000);
-	at76c651_set_qam(state, QAM_64);
-	at76c651_set_bbfreq(state);
-	at76c651_set_auto_config(state);
-
-	if (state->config->pll_init) {
-		at76c651_writereg(state, 0x0c, 0xc3);
-		state->config->pll_init(fe);
-		at76c651_writereg(state, 0x0c, 0xc2);
-	}
-
-	return 0;
-}
-
-static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-	struct at76c651_state* state = fe->demodulator_priv;
-	u8 sync;
-
-	/*
-	 * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0)
-	 */
-	sync = at76c651_readreg(state, 0x80);
-	*status = 0;
-
-	if (sync & (0x04 | 0x10))	/* AGC1 || TIM */
-		*status |= FE_HAS_SIGNAL;
-	if (sync & 0x10)		/* TIM */
-		*status |= FE_HAS_CARRIER;
-	if (sync & 0x80)		/* FEC */
-		*status |= FE_HAS_VITERBI;
-	if (sync & 0x40)		/* CAR */
-		*status |= FE_HAS_SYNC;
-	if ((sync & 0xF0) == 0xF0)	/* TIM && EQU && CAR && FEC */
-		*status |= FE_HAS_LOCK;
-
-	return 0;
-}
-
-static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-	struct at76c651_state* state = fe->demodulator_priv;
-
-	*ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16;
-	*ber |= at76c651_readreg(state, 0x82) << 8;
-	*ber |= at76c651_readreg(state, 0x83);
-	*ber *= 10;
-
-	return 0;
-}
-
-static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-	struct at76c651_state* state = fe->demodulator_priv;
-
-	u8 gain = ~at76c651_readreg(state, 0x91);
-	*strength = (gain << 8) | gain;
-
-	return 0;
-}
-
-static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-	struct at76c651_state* state = fe->demodulator_priv;
-
-	*snr = 0xFFFF -
-	    ((at76c651_readreg(state, 0x8F) << 8) |
-	     at76c651_readreg(state, 0x90));
-
-	return 0;
-}
-
-static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-	struct at76c651_state* state = fe->demodulator_priv;
-
-	*ucblocks = at76c651_readreg(state, 0x82);
-
-	return 0;
-}
-
-static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings)
-{
-	fesettings->min_delay_ms = 50;
-	fesettings->step_size = 0;
-	fesettings->max_drift = 0;
-	return 0;
-}
-
-static void at76c651_release(struct dvb_frontend* fe)
-{
-	struct at76c651_state* state = fe->demodulator_priv;
-	kfree(state);
-}
-
-static struct dvb_frontend_ops at76c651_ops;
-
-struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
-				     struct i2c_adapter* i2c)
-{
-	struct at76c651_state* state = NULL;
-
-	/* allocate memory for the internal state */
-	state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
-	if (state == NULL) goto error;
-
-	/* setup the state */
-	state->config = config;
-	state->qam = 0;
-
-	/* check if the demod is there */
-	if (at76c651_readreg(state, 0x0e) != 0x65) goto error;
-
-	/* finalise state setup */
-	state->i2c = i2c;
-	state->revision = at76c651_readreg(state, 0x0f) & 0xfe;
-	memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops));
-
-	/* create dvb_frontend */
-	state->frontend.ops = &state->ops;
-	state->frontend.demodulator_priv = state;
-	return &state->frontend;
-
-error:
-	kfree(state);
-	return NULL;
-}
-
-static struct dvb_frontend_ops at76c651_ops = {
-
-	.info = {
-		.name = "Atmel AT76C651B DVB-C",
-		.type = FE_QAM,
-		.frequency_min = 48250000,
-		.frequency_max = 863250000,
-		.frequency_stepsize = 62500,
-		/*.frequency_tolerance = */	/* FIXME: 12% of SR */
-		.symbol_rate_min = 0,		/* FIXME */
-		.symbol_rate_max = 9360000,	/* FIXME */
-		.symbol_rate_tolerance = 4000,
-		.caps = FE_CAN_INVERSION_AUTO |
-		    FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-		    FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-		    FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-		    FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 |
-		    FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER
-	},
-
-	.release = at76c651_release,
-
-	.init = at76c651_set_defaults,
-
-	.set_frontend = at76c651_set_parameters,
-	.get_tune_settings = at76c651_get_tune_settings,
-
-	.read_status = at76c651_read_status,
-	.read_ber = at76c651_read_ber,
-	.read_signal_strength = at76c651_read_signal_strength,
-	.read_snr = at76c651_read_snr,
-	.read_ucblocks = at76c651_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver");
-MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(at76c651_attach);
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h
deleted file mode 100644
index 34054df..0000000
--- a/drivers/media/dvb/frontends/at76c651.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * at76c651.c
- *
- * Atmel DVB-C Frontend Driver (at76c651)
- *
- * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
- *             & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *             & 2003 Wolfram Joost <dbox2@frokaschwei.de>
- *
- * 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.
- *
- * AT76C651
- * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
- * http://www.atmel.com/atmel/acrobat/doc1320.pdf
- */
-
-#ifndef AT76C651_H
-#define AT76C651_H
-
-#include <linux/dvb/frontend.h>
-
-struct at76c651_config
-{
-	/* the demodulator's i2c address */
-	u8 demod_address;
-
-	/* PLL maintenance */
-	int (*pll_init)(struct dvb_frontend* fe);
-	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-};
-
-extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
-					    struct i2c_adapter* i2c);
-
-#endif // AT76C651_H
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 1b9934e..4dcb605 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -326,11 +326,11 @@
 };
 EXPORT_SYMBOL(dvb_pll_tuv1236d);
 
-/* Samsung TBMV30111IN
+/* Samsung TBMV30111IN / TBMV30712IN1
  * used in Air2PC ATSC - 2nd generation (nxt2002)
  */
-struct dvb_pll_desc dvb_pll_tbmv30111in = {
-	.name = "Samsung TBMV30111IN",
+struct dvb_pll_desc dvb_pll_samsung_tbmv = {
+	.name = "Samsung TBMV30111IN / TBMV30712IN1",
 	.min = 54000000,
 	.max = 860000000,
 	.count = 6,
@@ -343,7 +343,7 @@
 		{ 999999999, 44000000, 166666, 0xfc, 0x02 },
 	}
 };
-EXPORT_SYMBOL(dvb_pll_tbmv30111in);
+EXPORT_SYMBOL(dvb_pll_samsung_tbmv);
 
 /*
  * Philips SD1878 Tuner.
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index f682c09..bb8d4b4 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -38,7 +38,7 @@
 
 extern struct dvb_pll_desc dvb_pll_tuv1236d;
 extern struct dvb_pll_desc dvb_pll_tdhu2;
-extern struct dvb_pll_desc dvb_pll_tbmv30111in;
+extern struct dvb_pll_desc dvb_pll_samsung_tbmv;
 extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
 
 int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
deleted file mode 100644
index 4f263e6..0000000
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
-    Support for B2C2/BBTI Technisat Air2PC - ATSC
-
-    Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net>
-
-    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.
-
-*/
-
-/*
- * This driver needs external firmware. Please use the command
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware
- * or /lib/firmware (depending on configuration of firmware hotplug).
- */
-#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
-#define CRC_CCIT_MASK 0x1021
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "nxt2002.h"
-
-struct nxt2002_state {
-
-	struct i2c_adapter* i2c;
-	struct dvb_frontend_ops ops;
-	const struct nxt2002_config* config;
-	struct dvb_frontend frontend;
-
-	/* demodulator private data */
-	u8 initialised:1;
-};
-
-static int debug;
-#define dprintk(args...) \
-	do { \
-		if (debug) printk(KERN_DEBUG "nxt2002: " args); \
-	} while (0)
-
-static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len)
-{
-	/* probbably a much better way or doing this */
-	u8 buf2 [256],x;
-	int err;
-	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
-
-	buf2[0] = reg;
-	for (x = 0 ; x < len ; x++)
-		buf2[x+1] = buf[x];
-
-	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-		printk ("%s: i2c write error (addr %02x, err == %i)\n",
-			__FUNCTION__, state->config->demod_address, err);
-		return -EREMOTEIO;
-	}
-
-	return 0;
-}
-
-static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len)
-{
-	u8 reg2 [] = { reg };
-
-	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
-			{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
-
-	int err;
-
-	if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
-		printk ("%s: i2c read error (addr %02x, err == %i)\n",
-			__FUNCTION__, state->config->demod_address, err);
-		return -EREMOTEIO;
-	}
-
-	return 0;
-}
-
-static u16 nxt2002_crc(u16 crc, u8 c)
-{
-
-	u8 i;
-	u16 input = (u16) c & 0xFF;
-
-	input<<=8;
-	for(i=0 ;i<8 ;i++) {
-		if((crc ^ input) & 0x8000)
-			crc=(crc<<1)^CRC_CCIT_MASK;
-		else
-			crc<<=1;
-	input<<=1;
-	}
-	return crc;
-}
-
-static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
-{
-	u8 buf;
-	dprintk("%s\n", __FUNCTION__);
-
-	/* set multi register length */
-	i2c_writebytes(state,0x34,&len,1);
-
-	/* set mutli register register */
-	i2c_writebytes(state,0x35,&reg,1);
-
-	/* send the actual data */
-	i2c_writebytes(state,0x36,data,len);
-
-	/* toggle the multireg write bit*/
-	buf = 0x02;
-	i2c_writebytes(state,0x21,&buf,1);
-
-	i2c_readbytes(state,0x21,&buf,1);
-
-	if ((buf & 0x02) == 0)
-		return 0;
-
-	dprintk("Error writing multireg register %02X\n",reg);
-
-	return 0;
-}
-
-static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
-{
-	u8 len2;
-	dprintk("%s\n", __FUNCTION__);
-
-	/* set multi register length */
-	len2 = len & 0x80;
-	i2c_writebytes(state,0x34,&len2,1);
-
-	/* set mutli register register */
-	i2c_writebytes(state,0x35,&reg,1);
-
-	/* send the actual data */
-	i2c_readbytes(state,reg,data,len);
-
-	return 0;
-}
-
-static void nxt2002_microcontroller_stop (struct nxt2002_state* state)
-{
-	u8 buf[2],counter = 0;
-	dprintk("%s\n", __FUNCTION__);
-
-	buf[0] = 0x80;
-	i2c_writebytes(state,0x22,buf,1);
-
-	while (counter < 20) {
-		i2c_readbytes(state,0x31,buf,1);
-		if (buf[0] & 0x40)
-			return;
-		msleep(10);
-		counter++;
-	}
-
-	dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n");
-	return;
-}
-
-static void nxt2002_microcontroller_start (struct nxt2002_state* state)
-{
-	u8 buf;
-	dprintk("%s\n", __FUNCTION__);
-
-	buf = 0x00;
-	i2c_writebytes(state,0x22,&buf,1);
-}
-
-static int nxt2002_writetuner (struct nxt2002_state* state, u8* data)
-{
-	u8 buf,count = 0;
-
-	dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]);
-
-	dprintk("%s\n", __FUNCTION__);
-	/* stop the micro first */
-	nxt2002_microcontroller_stop(state);
-
-	/* set the i2c transfer speed to the tuner */
-	buf = 0x03;
-	i2c_writebytes(state,0x20,&buf,1);
-
-	/* setup to transfer 4 bytes via i2c */
-	buf = 0x04;
-	i2c_writebytes(state,0x34,&buf,1);
-
-	/* write actual tuner bytes */
-	i2c_writebytes(state,0x36,data,4);
-
-	/* set tuner i2c address */
-	buf = 0xC2;
-	i2c_writebytes(state,0x35,&buf,1);
-
-	/* write UC Opmode to begin transfer */
-	buf = 0x80;
-	i2c_writebytes(state,0x21,&buf,1);
-
-	while (count < 20) {
-		i2c_readbytes(state,0x21,&buf,1);
-		if ((buf & 0x80)== 0x00)
-			return 0;
-		msleep(100);
-		count++;
-	}
-
-	printk("nxt2002: timeout error writing tuner\n");
-	return 0;
-}
-
-static void nxt2002_agc_reset(struct nxt2002_state* state)
-{
-	u8 buf;
-	dprintk("%s\n", __FUNCTION__);
-
-	buf = 0x08;
-	i2c_writebytes(state,0x08,&buf,1);
-
-	buf = 0x00;
-	i2c_writebytes(state,0x08,&buf,1);
-
-	return;
-}
-
-static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
-{
-
-	struct nxt2002_state* state = fe->demodulator_priv;
-	u8 buf[256],written = 0,chunkpos = 0;
-	u16 rambase,position,crc = 0;
-
-	dprintk("%s\n", __FUNCTION__);
-	dprintk("Firmware is %zu bytes\n",fw->size);
-
-	/* Get the RAM base for this nxt2002 */
-	i2c_readbytes(state,0x10,buf,1);
-
-	if (buf[0] & 0x10)
-		rambase = 0x1000;
-	else
-		rambase = 0x0000;
-
-	dprintk("rambase on this nxt2002 is %04X\n",rambase);
-
-	/* Hold the micro in reset while loading firmware */
-	buf[0] = 0x80;
-	i2c_writebytes(state,0x2B,buf,1);
-
-	for (position = 0; position < fw->size ; position++) {
-		if (written == 0) {
-			crc = 0;
-			chunkpos = 0x28;
-			buf[0] = ((rambase + position) >> 8);
-			buf[1] = (rambase + position) & 0xFF;
-			buf[2] = 0x81;
-			/* write starting address */
-			i2c_writebytes(state,0x29,buf,3);
-		}
-		written++;
-		chunkpos++;
-
-		if ((written % 4) == 0)
-			i2c_writebytes(state,chunkpos,&fw->data[position-3],4);
-
-		crc = nxt2002_crc(crc,fw->data[position]);
-
-		if ((written == 255) || (position+1 == fw->size)) {
-			/* write remaining bytes of firmware */
-			i2c_writebytes(state, chunkpos+4-(written %4),
-				&fw->data[position-(written %4) + 1],
-				written %4);
-			buf[0] = crc << 8;
-			buf[1] = crc & 0xFF;
-
-			/* write crc */
-			i2c_writebytes(state,0x2C,buf,2);
-
-			/* do a read to stop things */
-			i2c_readbytes(state,0x2A,buf,1);
-
-			/* set transfer mode to complete */
-			buf[0] = 0x80;
-			i2c_writebytes(state,0x2B,buf,1);
-
-			written = 0;
-		}
-	}
-
-	printk ("done.\n");
-	return 0;
-};
-
-static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
-					     struct dvb_frontend_parameters *p)
-{
-	struct nxt2002_state* state = fe->demodulator_priv;
-	u32 freq = 0;
-	u16 tunerfreq = 0;
-	u8 buf[4];
-
-	freq = 44000 + ( p->frequency / 1000 );
-
-	dprintk("freq = %d      p->frequency = %d\n",freq,p->frequency);
-
-	tunerfreq = freq * 24/4000;
-
-	buf[0] = (tunerfreq >> 8) & 0x7F;
-	buf[1] = (tunerfreq & 0xFF);
-
-	if (p->frequency <= 214000000) {
-		buf[2] = 0x84 + (0x06 << 3);
-		buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02;
-	} else if (p->frequency <= 721000000) {
-		buf[2] = 0x84 + (0x07 << 3);
-		buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08;
-	} else if (p->frequency <= 841000000) {
-		buf[2] = 0x84 + (0x0E << 3);
-		buf[3] = 0x08;
-	} else {
-		buf[2] = 0x84 + (0x0F << 3);
-		buf[3] = 0x02;
-	}
-
-	/* write frequency information */
-	nxt2002_writetuner(state,buf);
-
-	/* reset the agc now that tuning has been completed */
-	nxt2002_agc_reset(state);
-
-	/* set target power level */
-	switch (p->u.vsb.modulation) {
-		case QAM_64:
-		case QAM_256:
-				buf[0] = 0x74;
-				break;
-		case VSB_8:
-				buf[0] = 0x70;
-				break;
-		default:
-				return -EINVAL;
-				break;
-	}
-	i2c_writebytes(state,0x42,buf,1);
-
-	/* configure sdm */
-	buf[0] = 0x87;
-	i2c_writebytes(state,0x57,buf,1);
-
-	/* write sdm1 input */
-	buf[0] = 0x10;
-	buf[1] = 0x00;
-	nxt2002_writereg_multibyte(state,0x58,buf,2);
-
-	/* write sdmx input */
-	switch (p->u.vsb.modulation) {
-		case QAM_64:
-				buf[0] = 0x68;
-				break;
-		case QAM_256:
-				buf[0] = 0x64;
-				break;
-		case VSB_8:
-				buf[0] = 0x60;
-				break;
-		default:
-				return -EINVAL;
-				break;
-	}
-	buf[1] = 0x00;
-	nxt2002_writereg_multibyte(state,0x5C,buf,2);
-
-	/* write adc power lpf fc */
-	buf[0] = 0x05;
-	i2c_writebytes(state,0x43,buf,1);
-
-	/* write adc power lpf fc */
-	buf[0] = 0x05;
-	i2c_writebytes(state,0x43,buf,1);
-
-	/* write accumulator2 input */
-	buf[0] = 0x80;
-	buf[1] = 0x00;
-	nxt2002_writereg_multibyte(state,0x4B,buf,2);
-
-	/* write kg1 */
-	buf[0] = 0x00;
-	i2c_writebytes(state,0x4D,buf,1);
-
-	/* write sdm12 lpf fc */
-	buf[0] = 0x44;
-	i2c_writebytes(state,0x55,buf,1);
-
-	/* write agc control reg */
-	buf[0] = 0x04;
-	i2c_writebytes(state,0x41,buf,1);
-
-	/* write agc ucgp0 */
-	switch (p->u.vsb.modulation) {
-		case QAM_64:
-				buf[0] = 0x02;
-				break;
-		case QAM_256:
-				buf[0] = 0x03;
-				break;
-		case VSB_8:
-				buf[0] = 0x00;
-				break;
-		default:
-				return -EINVAL;
-				break;
-	}
-	i2c_writebytes(state,0x30,buf,1);
-
-	/* write agc control reg */
-	buf[0] = 0x00;
-	i2c_writebytes(state,0x41,buf,1);
-
-	/* write accumulator2 input */
-	buf[0] = 0x80;
-	buf[1] = 0x00;
-	nxt2002_writereg_multibyte(state,0x49,buf,2);
-	nxt2002_writereg_multibyte(state,0x4B,buf,2);
-
-	/* write agc control reg */
-	buf[0] = 0x04;
-	i2c_writebytes(state,0x41,buf,1);
-
-	nxt2002_microcontroller_start(state);
-
-	/* adjacent channel detection should be done here, but I don't
-	have any stations with this need so I cannot test it */
-
-	return 0;
-}
-
-static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-	struct nxt2002_state* state = fe->demodulator_priv;
-	u8 lock;
-	i2c_readbytes(state,0x31,&lock,1);
-
-	*status = 0;
-	if (lock & 0x20) {
-		*status |= FE_HAS_SIGNAL;
-		*status |= FE_HAS_CARRIER;
-		*status |= FE_HAS_VITERBI;
-		*status |= FE_HAS_SYNC;
-		*status |= FE_HAS_LOCK;
-	}
-	return 0;
-}
-
-static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-	struct nxt2002_state* state = fe->demodulator_priv;
-	u8 b[3];
-
-	nxt2002_readreg_multibyte(state,0xE6,b,3);
-
-	*ber = ((b[0] << 8) + b[1]) * 8;
-
-	return 0;
-}
-
-static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-	struct nxt2002_state* state = fe->demodulator_priv;
-	u8 b[2];
-	u16 temp = 0;
-
-	/* setup to read cluster variance */
-	b[0] = 0x00;
-	i2c_writebytes(state,0xA1,b,1);
-
-	/* get multreg val */
-	nxt2002_readreg_multibyte(state,0xA6,b,2);
-
-	temp = (b[0] << 8) | b[1];
-	*strength = ((0x7FFF - temp) & 0x0FFF) * 16;
-
-	return 0;
-}
-
-static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-
-	struct nxt2002_state* state = fe->demodulator_priv;
-	u8 b[2];
-	u16 temp = 0, temp2;
-	u32 snrdb = 0;
-
-	/* setup to read cluster variance */
-	b[0] = 0x00;
-	i2c_writebytes(state,0xA1,b,1);
-
-	/* get multreg val from 0xA6 */
-	nxt2002_readreg_multibyte(state,0xA6,b,2);
-
-	temp = (b[0] << 8) | b[1];
-	temp2 = 0x7FFF - temp;
-
-	/* snr will be in db */
-	if (temp2 > 0x7F00)
-		snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
-	else if (temp2 > 0x7EC0)
-		snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
-	else if (temp2 > 0x7C00)
-		snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
-	else
-		snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
-
-	/* the value reported back from the frontend will be FFFF=32db 0000=0db */
-
-	*snr = snrdb * (0xFFFF/32000);
-
-	return 0;
-}
-
-static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-	struct nxt2002_state* state = fe->demodulator_priv;
-	u8 b[3];
-
-	nxt2002_readreg_multibyte(state,0xE6,b,3);
-	*ucblocks = b[2];
-
-	return 0;
-}
-
-static int nxt2002_sleep(struct dvb_frontend* fe)
-{
-	return 0;
-}
-
-static int nxt2002_init(struct dvb_frontend* fe)
-{
-	struct nxt2002_state* state = fe->demodulator_priv;
-	const struct firmware *fw;
-	int ret;
-	u8 buf[2];
-
-	if (!state->initialised) {
-		/* request the firmware, this will block until someone uploads it */
-		printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
-		ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);
-		printk("nxt2002: Waiting for firmware upload(2)...\n");
-		if (ret) {
-			printk("nxt2002: no firmware upload (timeout or file not found?)\n");
-			return ret;
-		}
-
-		ret = nxt2002_load_firmware(fe, fw);
-		if (ret) {
-			printk("nxt2002: writing firmware to device failed\n");
-			release_firmware(fw);
-			return ret;
-		}
-		printk("nxt2002: firmware upload complete\n");
-
-		/* Put the micro into reset */
-		nxt2002_microcontroller_stop(state);
-
-		/* ensure transfer is complete */
-		buf[0]=0;
-		i2c_writebytes(state,0x2B,buf,1);
-
-		/* Put the micro into reset for real this time */
-		nxt2002_microcontroller_stop(state);
-
-		/* soft reset everything (agc,frontend,eq,fec)*/
-		buf[0] = 0x0F;
-		i2c_writebytes(state,0x08,buf,1);
-		buf[0] = 0x00;
-		i2c_writebytes(state,0x08,buf,1);
-
-		/* write agc sdm configure */
-		buf[0] = 0xF1;
-		i2c_writebytes(state,0x57,buf,1);
-
-		/* write mod output format */
-		buf[0] = 0x20;
-		i2c_writebytes(state,0x09,buf,1);
-
-		/* write fec mpeg mode */
-		buf[0] = 0x7E;
-		buf[1] = 0x00;
-		i2c_writebytes(state,0xE9,buf,2);
-
-		/* write mux selection */
-		buf[0] = 0x00;
-		i2c_writebytes(state,0xCC,buf,1);
-
-		state->initialised = 1;
-	}
-
-	return 0;
-}
-
-static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-	fesettings->min_delay_ms = 500;
-	fesettings->step_size = 0;
-	fesettings->max_drift = 0;
-	return 0;
-}
-
-static void nxt2002_release(struct dvb_frontend* fe)
-{
-	struct nxt2002_state* state = fe->demodulator_priv;
-	kfree(state);
-}
-
-static struct dvb_frontend_ops nxt2002_ops;
-
-struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
-				   struct i2c_adapter* i2c)
-{
-	struct nxt2002_state* state = NULL;
-	u8 buf [] = {0,0,0,0,0};
-
-	/* allocate memory for the internal state */
-	state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
-	if (state == NULL) goto error;
-
-	/* setup the state */
-	state->config = config;
-	state->i2c = i2c;
-	memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
-	state->initialised = 0;
-
-	/* Check the first 5 registers to ensure this a revision we can handle */
-
-	i2c_readbytes(state, 0x00, buf, 5);
-	if (buf[0] != 0x04) goto error;		/* device id */
-	if (buf[1] != 0x02) goto error;		/* fab id */
-	if (buf[2] != 0x11) goto error;		/* month */
-	if (buf[3] != 0x20) goto error;		/* year msb */
-	if (buf[4] != 0x00) goto error;		/* year lsb */
-
-	/* create dvb_frontend */
-	state->frontend.ops = &state->ops;
-	state->frontend.demodulator_priv = state;
-	return &state->frontend;
-
-error:
-	kfree(state);
-	return NULL;
-}
-
-static struct dvb_frontend_ops nxt2002_ops = {
-
-	.info = {
-		.name = "Nextwave nxt2002 VSB/QAM frontend",
-		.type = FE_ATSC,
-		.frequency_min =  54000000,
-		.frequency_max = 860000000,
-		/* stepsize is just a guess */
-		.frequency_stepsize = 166666,
-		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-			FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
-	},
-
-	.release = nxt2002_release,
-
-	.init = nxt2002_init,
-	.sleep = nxt2002_sleep,
-
-	.set_frontend = nxt2002_setup_frontend_parameters,
-	.get_tune_settings = nxt2002_get_tune_settings,
-
-	.read_status = nxt2002_read_status,
-	.read_ber = nxt2002_read_ber,
-	.read_signal_strength = nxt2002_read_signal_strength,
-	.read_snr = nxt2002_read_snr,
-	.read_ucblocks = nxt2002_read_ucblocks,
-
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
-MODULE_AUTHOR("Taylor Jacob");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(nxt2002_attach);
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h
deleted file mode 100644
index 462301f..0000000
--- a/drivers/media/dvb/frontends/nxt2002.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-   Driver for the Nxt2002 demodulator
-*/
-
-#ifndef NXT2002_H
-#define NXT2002_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct nxt2002_config
-{
-	/* the demodulator's i2c address */
-	u8 demod_address;
-
-	/* request firmware for device */
-	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-};
-
-extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
-					   struct i2c_adapter* i2c);
-
-#endif // NXT2002_H
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index 78d2b93..9e353539 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -1,9 +1,10 @@
 /*
  *    Support for NXT2002 and NXT2004 - VSB/QAM
  *
- *    Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
+ *    Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
+ *    Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
  *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
- *    and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
+ *    and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.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
@@ -614,7 +615,17 @@
 	/* write sdm1 input */
 	buf[0] = 0x10;
 	buf[1] = 0x00;
-	nxt200x_writebytes(state, 0x58, buf, 2);
+	switch (state->demod_chip) {
+		case NXT2002:
+			nxt200x_writereg_multibyte(state, 0x58, buf, 2);
+			break;
+		case NXT2004:
+			nxt200x_writebytes(state, 0x58, buf, 2);
+			break;
+		default:
+			return -EINVAL;
+			break;
+	}
 
 	/* write sdmx input */
 	switch (p->u.vsb.modulation) {
@@ -632,7 +643,17 @@
 				break;
 	}
 	buf[1] = 0x00;
-	nxt200x_writebytes(state, 0x5C, buf, 2);
+	switch (state->demod_chip) {
+		case NXT2002:
+			nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
+			break;
+		case NXT2004:
+			nxt200x_writebytes(state, 0x5C, buf, 2);
+			break;
+		default:
+			return -EINVAL;
+			break;
+	}
 
 	/* write adc power lpf fc */
 	buf[0] = 0x05;
@@ -648,7 +669,17 @@
 	/* write accumulator2 input */
 	buf[0] = 0x80;
 	buf[1] = 0x00;
-	nxt200x_writebytes(state, 0x4B, buf, 2);
+	switch (state->demod_chip) {
+		case NXT2002:
+			nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+			break;
+		case NXT2004:
+			nxt200x_writebytes(state, 0x4B, buf, 2);
+			break;
+		default:
+			return -EINVAL;
+			break;
+	}
 
 	/* write kg1 */
 	buf[0] = 0x00;
@@ -714,8 +745,19 @@
 	/* write accumulator2 input */
 	buf[0] = 0x80;
 	buf[1] = 0x00;
-	nxt200x_writebytes(state, 0x49, buf,2);
-	nxt200x_writebytes(state, 0x4B, buf,2);
+	switch (state->demod_chip) {
+		case NXT2002:
+			nxt200x_writereg_multibyte(state, 0x49, buf, 2);
+			nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+			break;
+		case NXT2004:
+			nxt200x_writebytes(state, 0x49, buf, 2);
+			nxt200x_writebytes(state, 0x4B, buf, 2);
+			break;
+		default:
+			return -EINVAL;
+			break;
+	}
 
 	/* write agc control reg */
 	buf[0] = 0x04;
@@ -1199,7 +1241,7 @@
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
 MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
-MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
+MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(nxt200x_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
deleted file mode 100644
index d1cabb6..0000000
--- a/drivers/media/dvb/frontends/tda80xx.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * tda80xx.c
- *
- * Philips TDA8044 / TDA8083 QPSK demodulator driver
- *
- * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/config.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/irq.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "tda80xx.h"
-
-enum {
-	ID_TDA8044 = 0x04,
-	ID_TDA8083 = 0x05,
-};
-
-
-struct tda80xx_state {
-
-	struct i2c_adapter* i2c;
-
-	struct dvb_frontend_ops ops;
-
-	/* configuration settings */
-	const struct tda80xx_config* config;
-
-	struct dvb_frontend frontend;
-
-	u32 clk;
-	int afc_loop;
-	struct work_struct worklet;
-	fe_code_rate_t code_rate;
-	fe_spectral_inversion_t spectral_inversion;
-	fe_status_t status;
-	u8 id;
-};
-
-static int debug = 1;
-#define dprintk	if (debug) printk
-
-static u8 tda8044_inittab_pre[] = {
-	0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
-	0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58,
-	0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
-	0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00,
-	0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00
-};
-
-static u8 tda8044_inittab_post[] = {
-	0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
-	0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50,
-	0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
-	0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c,
-	0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00
-};
-
-static u8 tda8083_inittab[] = {
-	0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
-	0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
-	0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
-	0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
-	0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00
-};
-
-static __inline__ u32 tda80xx_div(u32 a, u32 b)
-{
-	return (a + (b / 2)) / b;
-}
-
-static __inline__ u32 tda80xx_gcd(u32 a, u32 b)
-{
-	u32 r;
-
-	while ((r = a % b)) {
-		a = b;
-		b = r;
-	}
-
-	return b;
-}
-
-static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len)
-{
-	int ret;
-	struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
-			  { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
-
-	ret = i2c_transfer(state->i2c, msg, 2);
-
-	if (ret != 2)
-		dprintk("%s: readreg error (reg %02x, ret == %i)\n",
-				__FUNCTION__, reg, ret);
-
-	mdelay(10);
-
-	return (ret == 2) ? 0 : -EREMOTEIO;
-}
-
-static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len)
-{
-	int ret;
-	u8 wbuf[len + 1];
-	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 };
-
-	wbuf[0] = reg;
-	memcpy(&wbuf[1], buf, len);
-
-	ret = i2c_transfer(state->i2c, &msg, 1);
-
-	if (ret != 1)
-		dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret);
-
-	mdelay(10);
-
-	return (ret == 1) ? 0 : -EREMOTEIO;
-}
-
-static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg)
-{
-	u8 val;
-
-	tda80xx_read(state, reg, &val, 1);
-
-	return val;
-}
-
-static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data)
-{
-	return tda80xx_write(state, reg, &data, 1);
-}
-
-static int tda80xx_set_parameters(struct tda80xx_state* state,
-				  fe_spectral_inversion_t inversion,
-				  u32 symbol_rate,
-				  fe_code_rate_t fec_inner)
-{
-	u8 buf[15];
-	u64 ratio;
-	u32 clk;
-	u32 k;
-	u32 sr = symbol_rate;
-	u32 gcd;
-	u8 scd;
-
-	if (symbol_rate > (state->clk * 3) / 16)
-		scd = 0;
-	else if (symbol_rate > (state->clk * 3) / 32)
-		scd = 1;
-	else if (symbol_rate > (state->clk * 3) / 64)
-		scd = 2;
-	else
-		scd = 3;
-
-	clk = scd ? (state->clk / (scd * 2)) : state->clk;
-
-	/*
-	 * Viterbi decoder:
-	 * Differential decoding off
-	 * Spectral inversion unknown
-	 * QPSK modulation
-	 */
-	if (inversion == INVERSION_ON)
-		buf[0] = 0x60;
-	else if (inversion == INVERSION_OFF)
-		buf[0] = 0x20;
-	else
-		buf[0] = 0x00;
-
-	/*
-	 * CLK ratio:
-	 * system clock frequency is up to 64 or 96 MHz
-	 *
-	 * formula:
-	 * r = k * clk / symbol_rate
-	 *
-	 * k:	2^21 for caa 0..3,
-	 *	2^20 for caa 4..5,
-	 *	2^19 for caa 6..7
-	 */
-	if (symbol_rate <= (clk * 3) / 32)
-		k = (1 << 19);
-	else if (symbol_rate <= (clk * 3) / 16)
-		k = (1 << 20);
-	else
-		k = (1 << 21);
-
-	gcd = tda80xx_gcd(clk, sr);
-	clk /= gcd;
-	sr /= gcd;
-
-	gcd = tda80xx_gcd(k, sr);
-	k /= gcd;
-	sr /= gcd;
-
-	ratio = (u64)k * (u64)clk;
-	do_div(ratio, sr);
-
-	buf[1] = ratio >> 16;
-	buf[2] = ratio >> 8;
-	buf[3] = ratio;
-
-	/* nyquist filter roll-off factor 35% */
-	buf[4] = 0x20;
-
-	clk = scd ? (state->clk / (scd * 2)) : state->clk;
-
-	/* Anti Alias Filter */
-	if (symbol_rate < (clk * 3) / 64)
-		printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate);
-	else if (symbol_rate <= clk / 16)
-		buf[4] |= 0x07;
-	else if (symbol_rate <= (clk * 3) / 32)
-		buf[4] |= 0x06;
-	else if (symbol_rate <= clk / 8)
-		buf[4] |= 0x05;
-	else if (symbol_rate <= (clk * 3) / 16)
-		buf[4] |= 0x04;
-	else if (symbol_rate <= clk / 4)
-		buf[4] |= 0x03;
-	else if (symbol_rate <= (clk * 3) / 8)
-		buf[4] |= 0x02;
-	else if (symbol_rate <= clk / 2)
-		buf[4] |= 0x01;
-	else
-		buf[4] |= 0x00;
-
-	/* Sigma Delta converter */
-	buf[5] = 0x00;
-
-	/* FEC: Possible puncturing rates */
-	if (fec_inner == FEC_NONE)
-		buf[6] = 0x00;
-	else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9))
-		buf[6] = (1 << (8 - fec_inner));
-	else if (fec_inner == FEC_AUTO)
-		buf[6] = 0xff;
-	else
-		return -EINVAL;
-
-	/* carrier lock detector threshold value */
-	buf[7] = 0x30;
-	/* AFC1: proportional part settings */
-	buf[8] = 0x42;
-	/* AFC1: integral part settings */
-	buf[9] = 0x98;
-	/* PD: Leaky integrator SCPC mode */
-	buf[10] = 0x28;
-	/* AFC2, AFC1 controls */
-	buf[11] = 0x30;
-	/* PD: proportional part settings */
-	buf[12] = 0x42;
-	/* PD: integral part settings */
-	buf[13] = 0x99;
-	/* AGC */
-	buf[14] = 0x50 | scd;
-
-	printk("symbol_rate=%u clk=%u\n", symbol_rate, clk);
-
-	return tda80xx_write(state, 0x01, buf, sizeof(buf));
-}
-
-static int tda80xx_set_clk(struct tda80xx_state* state)
-{
-	u8 buf[2];
-
-	/* CLK proportional part */
-	buf[0] = (0x06 << 5) | 0x08;	/* CMP[2:0], CSP[4:0] */
-	/* CLK integral part */
-	buf[1] = (0x04 << 5) | 0x1a;	/* CMI[2:0], CSI[4:0] */
-
-	return tda80xx_write(state, 0x17, buf, sizeof(buf));
-}
-
-#if 0
-static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state)
-{
-	/* a constant value is nonsense here imho */
-	return tda80xx_writereg(state, 0x22, 0xf9);
-}
-#endif
-
-static int tda80xx_close_loop(struct tda80xx_state* state)
-{
-	u8 buf[2];
-
-	/* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */
-	buf[0] = 0x68;
-	/* AFC1: Loop closed, CAR Feedback: 8192 */
-	buf[1] = 0x70;
-
-	return tda80xx_write(state, 0x0b, buf, sizeof(buf));
-}
-
-static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt)
-{
-	schedule_work(priv);
-
-	return IRQ_HANDLED;
-}
-
-static void tda80xx_read_status_int(struct tda80xx_state* state)
-{
-	u8 val;
-
-	static const fe_spectral_inversion_t inv_tab[] = {
-		INVERSION_OFF, INVERSION_ON
-	};
-
-	static const fe_code_rate_t fec_tab[] = {
-		FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
-		FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8,
-	};
-
-	val = tda80xx_readreg(state, 0x02);
-
-	state->status = 0;
-
-	if (val & 0x01) /* demodulator lock */
-		state->status |= FE_HAS_SIGNAL;
-	if (val & 0x02) /* clock recovery lock */
-		state->status |= FE_HAS_CARRIER;
-	if (val & 0x04) /* viterbi lock */
-		state->status |= FE_HAS_VITERBI;
-	if (val & 0x08) /* deinterleaver lock (packet sync) */
-		state->status |= FE_HAS_SYNC;
-	if (val & 0x10) /* derandomizer lock (frame sync) */
-		state->status |= FE_HAS_LOCK;
-	if (val & 0x20) /* frontend can not lock */
-		state->status |= FE_TIMEDOUT;
-
-	if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) {
-		printk("tda80xx: closing loop\n");
-		tda80xx_close_loop(state);
-		state->afc_loop = 0;
-	}
-
-	if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) {
-		val = tda80xx_readreg(state, 0x0e);
-		state->code_rate = fec_tab[val & 0x07];
-		if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK))
-			state->spectral_inversion = inv_tab[(val >> 7) & 0x01];
-		else
-			state->spectral_inversion = INVERSION_AUTO;
-	}
-	else {
-		state->code_rate = FEC_AUTO;
-	}
-}
-
-static void tda80xx_worklet(void *priv)
-{
-	struct tda80xx_state *state = priv;
-
-	tda80xx_writereg(state, 0x00, 0x04);
-	enable_irq(state->config->irq);
-
-	tda80xx_read_status_int(state);
-}
-
-static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state)
-{
-	size_t i;
-
-	for (i = 0; i < 100; i++) {
-		if (tda80xx_readreg(state, 0x02) & 0x80)
-			break;
-		msleep(10);
-	}
-}
-
-static int tda8044_init(struct dvb_frontend* fe)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-	int ret;
-
-	/*
-	 * this function is a mess...
-	 */
-
-	if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre))))
-		return ret;
-
-	tda80xx_writereg(state, 0x0f, 0x50);
-#if 1
-	tda80xx_writereg(state, 0x20, 0x8F);		/* FIXME */
-	tda80xx_writereg(state, 0x20, state->config->volt18setting);	/* FIXME */
-	//tda80xx_writereg(state, 0x00, 0x04);
-	tda80xx_writereg(state, 0x00, 0x0C);
-#endif
-	//tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */
-
-	tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post));
-
-	if (state->config->pll_init) {
-		tda80xx_writereg(state, 0x1c, 0x80);
-		state->config->pll_init(fe);
-		tda80xx_writereg(state, 0x1c, 0x00);
-	}
-
-	return 0;
-}
-
-static int tda8083_init(struct dvb_frontend* fe)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab));
-
-	if (state->config->pll_init) {
-		tda80xx_writereg(state, 0x1c, 0x80);
-		state->config->pll_init(fe);
-		tda80xx_writereg(state, 0x1c, 0x00);
-	}
-
-	return 0;
-}
-
-static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	switch (voltage) {
-	case SEC_VOLTAGE_13:
-		return tda80xx_writereg(state, 0x20, state->config->volt13setting);
-	case SEC_VOLTAGE_18:
-		return tda80xx_writereg(state, 0x20, state->config->volt18setting);
-	case SEC_VOLTAGE_OFF:
-		return tda80xx_writereg(state, 0x20, 0);
-	default:
-		return -EINVAL;
-	}
-}
-
-static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	switch (tone) {
-	case SEC_TONE_OFF:
-		return tda80xx_writereg(state, 0x29, 0x00);
-	case SEC_TONE_ON:
-		return tda80xx_writereg(state, 0x29, 0x80);
-	default:
-		return -EINVAL;
-	}
-}
-
-static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	if (cmd->msg_len > 6)
-		return -EINVAL;
-
-	tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3));
-	tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len);
-	tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3));
-	tda80xx_wait_diseqc_fifo(state);
-
-	return 0;
-}
-
-static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	switch (cmd) {
-	case SEC_MINI_A:
-		tda80xx_writereg(state, 0x29, 0x14);
-		break;
-	case SEC_MINI_B:
-		tda80xx_writereg(state, 0x29, 0x1c);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	tda80xx_wait_diseqc_fifo(state);
-
-	return 0;
-}
-
-static int tda80xx_sleep(struct dvb_frontend* fe)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	tda80xx_writereg(state, 0x00, 0x02);	/* enter standby */
-
-	return 0;
-}
-
-static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	tda80xx_writereg(state, 0x1c, 0x80);
-	state->config->pll_set(fe, p);
-	tda80xx_writereg(state, 0x1c, 0x00);
-
-	tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner);
-	tda80xx_set_clk(state);
-	//tda80xx_set_scpc_freq_offset(state);
-	state->afc_loop = 1;
-
-	return 0;
-}
-
-static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	if (!state->config->irq)
-		tda80xx_read_status_int(state);
-
-	p->inversion = state->spectral_inversion;
-	p->u.qpsk.fec_inner = state->code_rate;
-
-	return 0;
-}
-
-static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	if (!state->config->irq)
-		tda80xx_read_status_int(state);
-	*status = state->status;
-
-	return 0;
-}
-
-static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-	int ret;
-	u8 buf[3];
-
-	if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf))))
-		return ret;
-
-	*ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
-
-	return 0;
-}
-
-static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	u8 gain = ~tda80xx_readreg(state, 0x01);
-	*strength = (gain << 8) | gain;
-
-	return 0;
-}
-
-static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	u8 quality = tda80xx_readreg(state, 0x08);
-	*snr = (quality << 8) | quality;
-
-	return 0;
-}
-
-static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	*ucblocks = tda80xx_readreg(state, 0x0f);
-	if (*ucblocks == 0xff)
-		*ucblocks = 0xffffffff;
-
-	return 0;
-}
-
-static int tda80xx_init(struct dvb_frontend* fe)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	switch(state->id) {
-	case ID_TDA8044:
-		return tda8044_init(fe);
-
-	case ID_TDA8083:
-		return tda8083_init(fe);
-	}
-	return 0;
-}
-
-static void tda80xx_release(struct dvb_frontend* fe)
-{
-	struct tda80xx_state* state = fe->demodulator_priv;
-
-	if (state->config->irq)
-		free_irq(state->config->irq, &state->worklet);
-
-	kfree(state);
-}
-
-static struct dvb_frontend_ops tda80xx_ops;
-
-struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
-				    struct i2c_adapter* i2c)
-{
-	struct tda80xx_state* state = NULL;
-	int ret;
-
-	/* allocate memory for the internal state */
-	state = kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
-	if (state == NULL) goto error;
-
-	/* setup the state */
-	state->config = config;
-	state->i2c = i2c;
-	memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops));
-	state->spectral_inversion = INVERSION_AUTO;
-	state->code_rate = FEC_AUTO;
-	state->status = 0;
-	state->afc_loop = 0;
-
-	/* check if the demod is there */
-	if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error;
-	state->id = tda80xx_readreg(state, 0x00);
-
-	switch (state->id) {
-	case ID_TDA8044:
-		state->clk = 96000000;
-		printk("tda80xx: Detected tda8044\n");
-		break;
-
-	case ID_TDA8083:
-		state->clk = 64000000;
-		printk("tda80xx: Detected tda8083\n");
-		break;
-
-	default:
-		goto error;
-	}
-
-	/* setup IRQ */
-	if (state->config->irq) {
-		INIT_WORK(&state->worklet, tda80xx_worklet, state);
-		if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) {
-			printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret);
-			goto error;
-		}
-	}
-
-	/* create dvb_frontend */
-	state->frontend.ops = &state->ops;
-	state->frontend.demodulator_priv = state;
-	return &state->frontend;
-
-error:
-	kfree(state);
-	return NULL;
-}
-
-static struct dvb_frontend_ops tda80xx_ops = {
-
-	.info = {
-		.name = "Philips TDA80xx DVB-S",
-		.type = FE_QPSK,
-		.frequency_min = 500000,
-		.frequency_max = 2700000,
-		.frequency_stepsize = 125,
-		.symbol_rate_min = 4500000,
-		.symbol_rate_max = 45000000,
-		.caps =	FE_CAN_INVERSION_AUTO |
-			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-			FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-			FE_CAN_QPSK |
-			FE_CAN_MUTE_TS
-	},
-
-	.release = tda80xx_release,
-
-	.init = tda80xx_init,
-	.sleep = tda80xx_sleep,
-
-	.set_frontend = tda80xx_set_frontend,
-	.get_frontend = tda80xx_get_frontend,
-
-	.read_status = tda80xx_read_status,
-	.read_ber = tda80xx_read_ber,
-	.read_signal_strength = tda80xx_read_signal_strength,
-	.read_snr = tda80xx_read_snr,
-	.read_ucblocks = tda80xx_read_ucblocks,
-
-	.diseqc_send_master_cmd = tda80xx_send_diseqc_msg,
-	.diseqc_send_burst = tda80xx_send_diseqc_burst,
-	.set_tone = tda80xx_set_tone,
-	.set_voltage = tda80xx_set_voltage,
-};
-
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver");
-MODULE_AUTHOR("Felix Domke, Andreas Oberritter");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda80xx_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h
deleted file mode 100644
index cd639a0..0000000
--- a/drivers/media/dvb/frontends/tda80xx.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * tda80xx.c
- *
- * Philips TDA8044 / TDA8083 QPSK demodulator driver
- *
- * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef TDA80XX_H
-#define TDA80XX_H
-
-#include <linux/dvb/frontend.h>
-
-struct tda80xx_config
-{
-	/* the demodulator's i2c address */
-	u8 demod_address;
-
-	/* IRQ to use (0=>no IRQ used) */
-	u32 irq;
-
-	/* Register setting to use for 13v */
-	u8 volt13setting;
-
-	/* Register setting to use for 18v */
-	u8 volt18setting;
-
-	/* PLL maintenance */
-	int (*pll_init)(struct dvb_frontend* fe);
-	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-};
-
-extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
-					   struct i2c_adapter* i2c);
-
-#endif // TDA80XX_H
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 2749490..d36369e 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -2329,6 +2329,17 @@
 			av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
 			break;
 
+		case 0x0004: // Galaxis DVB-S rev1.3
+			/* ALPS BSRV2 */
+			av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+			if (av7110->fe) {
+				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
+				av7110->fe->ops->set_tone = av7110_set_tone;
+				av7110->recover = dvb_s_recover;
+			}
+			break;
+
 		case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
 			/* Grundig 29504-451 */
 			av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
@@ -2930,6 +2941,7 @@
 MAKE_AV7110_INFO(ttt,        "Technotrend/Hauppauge DVB-T");
 MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
 MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
+MAKE_AV7110_INFO(gxs_1_3,    "Galaxis DVB-S rev1.3");
 
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(fsc,         0x110a, 0x0000),
@@ -2937,13 +2949,13 @@
 	MAKE_EXTENSION_PCI(ttt_1_X,     0x13c2, 0x0001),
 	MAKE_EXTENSION_PCI(ttc_2_X,     0x13c2, 0x0002),
 	MAKE_EXTENSION_PCI(tts_2_X,     0x13c2, 0x0003),
+	MAKE_EXTENSION_PCI(gxs_1_3,     0x13c2, 0x0004),
 	MAKE_EXTENSION_PCI(fss,         0x13c2, 0x0006),
 	MAKE_EXTENSION_PCI(ttt,         0x13c2, 0x0008),
 	MAKE_EXTENSION_PCI(ttc_1_X,     0x13c2, 0x000a),
 	MAKE_EXTENSION_PCI(tts_2_3,     0x13c2, 0x000e),
 	MAKE_EXTENSION_PCI(tts_1_3se,   0x13c2, 0x1002),
 
-/*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
 /*	MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
 
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 6ea30df..fafd25f 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -273,8 +273,6 @@
 extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
 		       u16 subpid, u16 pcrpid);
 
-extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
-
 extern int av7110_ir_init(struct av7110 *av7110);
 extern void av7110_ir_exit(struct av7110 *av7110);
 
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 9138132..617e4f6 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -155,6 +155,19 @@
 }
 
 
+static int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
+{
+	int ret = 0;
+
+	dprintk(4, "%p\n", av7110);
+	if (av7110) {
+		ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
+		av7110->ir_config = ir_config;
+	}
+	return ret;
+}
+
+
 static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
 				unsigned long count, void *data)
 {
@@ -187,19 +200,6 @@
 }
 
 
-int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
-{
-	int ret = 0;
-
-	dprintk(4, "%p\n", av7110);
-	if (av7110) {
-		ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
-		av7110->ir_config = ir_config;
-	}
-	return ret;
-}
-
-
 static void ir_handler(struct av7110 *av7110, u32 ircom)
 {
 	dprintk(4, "ircommand = %08x\n", ircom);
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index aa4c4c5..578b200 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -214,7 +214,7 @@
 		   we can capture, of the first and second field. */
 		.vbistart	= { 7,320 },
 	},{
-		.v4l2_id        = V4L2_STD_NTSC_M,
+		.v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
 		.name           = "NTSC",
 		.Fsc            = 28636363,
 		.swidth         = 768,
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
index 297c32a..840fe01 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/compat_ioctl32.c
@@ -167,29 +167,32 @@
 	if (kp->clipcount > 2048)
 		return -EINVAL;
 	if (kp->clipcount) {
-		struct v4l2_clip32 *uclips = compat_ptr(up->clips);
-		struct v4l2_clip *kclips;
+		struct v4l2_clip32 __user *uclips;
+		struct v4l2_clip __user *kclips;
 		int n = kp->clipcount;
+		compat_caddr_t p;
 
+		if (get_user(p, &up->clips))
+			return -EFAULT;
+		uclips = compat_ptr(p);
 		kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
 		kp->clips = kclips;
 		while (--n >= 0) {
-			if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) ||
-				copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
+			if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
 				return -EFAULT;
-			kclips->next = n ? kclips + 1 : 0;
+			if (put_user(n ? kclips + 1 : NULL, &kclips->next))
+				return -EFAULT;
 			uclips += 1;
 			kclips += 1;
 		}
 	} else
-		kp->clips = 0;
+		kp->clips = NULL;
 	return 0;
 }
 
 static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) ||
-		copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
+	if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
 		put_user(kp->field, &up->field) ||
 		put_user(kp->chromakey, &up->chromakey) ||
 		put_user(kp->clipcount, &up->clipcount))
@@ -199,33 +202,29 @@
 
 static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) ||
-		copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
-			return -EFAULT;
+	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
+		return -EFAULT;
 	return 0;
 }
 
 static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) ||
-		copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
-			return -EFAULT;
+	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
+		return -EFAULT;
 	return 0;
 }
 
 static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) ||
-		copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
-			return -EFAULT;
+	if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
+		return -EFAULT;
 	return 0;
 }
 
 static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) ||
-		copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
-			return -EFAULT;
+	if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -279,18 +278,16 @@
 
 static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) ||
-		copy_from_user(kp, up, sizeof(struct v4l2_standard)))
-			return -EFAULT;
+	if (copy_from_user(kp, up, sizeof(struct v4l2_standard)))
+		return -EFAULT;
 	return 0;
 
 }
 
 static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) ||
-		copy_to_user(up, kp, sizeof(struct v4l2_standard)))
-			return -EFAULT;
+	if (copy_to_user(up, kp, sizeof(struct v4l2_standard)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -328,18 +325,16 @@
 
 static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) ||
-		copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
-			return -EFAULT;
+	if (copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
+		return -EFAULT;
 	return 0;
 
 }
 
 static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) ||
-		copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
-			return -EFAULT;
+	if (copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -380,11 +375,13 @@
 		break;
 	case V4L2_MEMORY_USERPTR:
 		{
-		unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr);
+		compat_long_t tmp;
 
-		if(get_user(kp->length, &up->length) ||
-			get_user(kp->m.userptr, &tmp))
-				return -EFAULT;
+		if (get_user(kp->length, &up->length) ||
+		    get_user(tmp, &up->m.userptr))
+			return -EFAULT;
+
+		kp->m.userptr = (unsigned long)compat_ptr(tmp);
 		}
 		break;
 	case V4L2_MEMORY_OVERLAY:
@@ -468,33 +465,29 @@
 
 static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) ||
-		copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
-			return -EFAULT;
+	if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
+		return -EFAULT;
 	return 0;
 }
 
 static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) ||
-		copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
-			return -EFAULT;
+	if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
+		return -EFAULT;
 	return 0;
 }
 
 static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) ||
-		copy_from_user(kp, up, sizeof(struct v4l2_input)))
-			return -EFAULT;
+	if (copy_from_user(kp, up, sizeof(struct v4l2_input)))
+		return -EFAULT;
 	return 0;
 }
 
 static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) ||
-		copy_to_user(up, kp, sizeof(struct v4l2_input)))
-			return -EFAULT;
+	if (copy_to_user(up, kp, sizeof(struct v4l2_input)))
+		return -EFAULT;
 	return 0;
 }
 
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index c66c2c1..08ffd1f 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -220,33 +220,23 @@
 		cx25840_write(client, 0x808, 0xff);
 		cx25840_write(client, 0x80b, 0x10);
 	} else if (std & V4L2_STD_NTSC) {
-		/* NTSC */
-		if (state->pvr150_workaround) {
-			/* Certain Hauppauge PVR150 models have a hardware bug
-			   that causes audio to drop out. For these models the
-			   audio standard must be set explicitly.
-			   To be precise: it affects cards with tuner models
-			   85, 99 and 112 (model numbers from tveeprom). */
-			if (std == V4L2_STD_NTSC_M_JP) {
-				/* Japan uses EIAJ audio standard */
-				cx25840_write(client, 0x808, 0x2f);
-			} else {
-				/* Others use the BTSC audio standard */
-				cx25840_write(client, 0x808, 0x1f);
-			}
-			/* South Korea uses the A2-M (aka Zweiton M) audio
-			   standard, and should set 0x808 to 0x3f, but I don't
-			   know how to detect this. */
-		} else if (std == V4L2_STD_NTSC_M_JP) {
+		/* Certain Hauppauge PVR150 models have a hardware bug
+		   that causes audio to drop out. For these models the
+		   audio standard must be set explicitly.
+		   To be precise: it affects cards with tuner models
+		   85, 99 and 112 (model numbers from tveeprom). */
+		int hw_fix = state->pvr150_workaround;
+
+		if (std == V4L2_STD_NTSC_M_JP) {
 			/* Japan uses EIAJ audio standard */
-			cx25840_write(client, 0x808, 0xf7);
+			cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
+		} else if (std == V4L2_STD_NTSC_M_KR) {
+			/* South Korea uses A2 audio standard */
+			cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
 		} else {
 			/* Others use the BTSC audio standard */
-			cx25840_write(client, 0x808, 0xf6);
+			cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
 		}
-		/* South Korea uses the A2-M (aka Zweiton M) audio standard,
-		   and should set 0x808 to 0xf8, but I don't know how to
-		   detect this. */
 		cx25840_write(client, 0x80b, 0x00);
 	}
 
@@ -330,17 +320,17 @@
 	u8 fmt=0; 	/* zero is autodetect */
 
 	/* First tests should be against specific std */
-	if (std & V4L2_STD_NTSC_M_JP) {
+	if (std == V4L2_STD_NTSC_M_JP) {
 		fmt=0x2;
-	} else if (std & V4L2_STD_NTSC_443) {
+	} else if (std == V4L2_STD_NTSC_443) {
 		fmt=0x3;
-	} else if (std & V4L2_STD_PAL_M) {
+	} else if (std == V4L2_STD_PAL_M) {
 		fmt=0x5;
-	} else if (std & V4L2_STD_PAL_N) {
+	} else if (std == V4L2_STD_PAL_N) {
 		fmt=0x6;
-	} else if (std & V4L2_STD_PAL_Nc) {
+	} else if (std == V4L2_STD_PAL_Nc) {
 		fmt=0x7;
-	} else if (std & V4L2_STD_PAL_60) {
+	} else if (std == V4L2_STD_PAL_60) {
 		fmt=0x8;
 	} else {
 		/* Then, test against generic ones */
@@ -369,7 +359,7 @@
 	}
 
 	switch (fmt) {
-	case 0x1: return V4L2_STD_NTSC_M;
+	case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR;
 	case 0x2: return V4L2_STD_NTSC_M_JP;
 	case 0x3: return V4L2_STD_NTSC_443;
 	case 0x4: return V4L2_STD_PAL;
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 5330891..e99dfbb 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -32,6 +32,7 @@
 config VIDEO_CX88_ALSA
 	tristate "ALSA DMA audio support"
 	depends on VIDEO_CX88 && SND && EXPERIMENTAL
+	select SND_PCM
 	---help---
 	  This is a video4linux driver for direct (DMA) audio on
 	  Conexant 2388x based TV cards.
@@ -48,6 +49,7 @@
 	default y
 	depends on VIDEO_CX88_DVB
 	select DVB_MT352
+	select VIDEO_CX88_VP3054
 	select DVB_OR51132
 	select DVB_CX22702
 	select DVB_LGDT330X
@@ -69,6 +71,16 @@
 	  This adds DVB-T support for cards based on the
 	  Connexant 2388x chip and the MT352 demodulator.
 
+config VIDEO_CX88_VP3054
+	tristate "VP-3054 Secondary I2C Bus Support"
+	default m
+	depends on DVB_MT352
+	---help---
+	  This adds DVB-T support for cards based on the
+	  Connexant 2388x chip and the MT352 demodulator,
+	  which also require support for the VP-3054
+	  Secondary I2C bus, such at DNTV Live! DVB-T Pro.
+
 config VIDEO_CX88_DVB_OR51132
 	bool "OR51132 ATSC Support"
 	default y
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 6e5eaa2..2b90278 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -4,8 +4,9 @@
 cx8802-objs	:= cx88-mpeg.o
 
 obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
-obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o
+obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
 obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
+obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
 
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
@@ -18,6 +19,6 @@
 extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
 extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
 extra-cflags-$(CONFIG_DVB_CX24123)   += -DHAVE_CX24123=1
-extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1
+extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1
 
 EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index a2e36a1..2acccd6 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -128,7 +128,7 @@
  * BOARD Specific: Sets audio DMA
  */
 
-int _cx88_start_audio_dma(snd_cx88_card_t *chip)
+static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
 {
 	struct cx88_buffer   *buf = chip->buf;
 	struct cx88_core *core=chip->core;
@@ -173,7 +173,7 @@
 /*
  * BOARD Specific: Resets audio DMA
  */
-int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
+static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
 {
 	struct cx88_core *core=chip->core;
 	dprintk(1, "Stopping audio DMA\n");
@@ -613,7 +613,7 @@
  * Only boards with eeprom and byte 1 at eeprom=1 have it
  */
 
-struct pci_device_id cx88_audio_pci_tbl[] = {
+static struct pci_device_id cx88_audio_pci_tbl[] = {
 	{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
 	{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
 	{0, }
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index ad2f565..1bc9992 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1246,6 +1246,11 @@
 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
 	},{
 		.subvendor = 0x18ac,
+		.subdevice = 0xdb54,
+		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
+		/* Re-branded DViCO: DigitalNow DVB-T Dual */
+	},{
+		.subvendor = 0x18ac,
 		.subdevice = 0xdb11,
 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
 		/* Re-branded DViCO: UltraView DVB-T Plus */
@@ -1293,6 +1298,7 @@
 	switch (tv.model)
 	{
 	case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
+	case 34519: /* WinTV-PCI-FM */
 	case 90002: /* Nova-T-PCI (9002) */
 	case 92001: /* Nova-S-Plus (Video and IR) */
 	case 92002: /* Nova-S-Plus (Video and IR) */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 8d6d6a6..3720f24a 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -787,12 +787,14 @@
 
 int cx88_start_audio_dma(struct cx88_core *core)
 {
+	/* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
+	int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
 	/* setup fifo + format */
-	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
-	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
+	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
+	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
 
-	cx_write(MO_AUDD_LNGTH,    128); /* fifo bpl size */
-	cx_write(MO_AUDR_LNGTH,    128); /* fifo bpl size */
+	cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
+	cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
 
 	/* start dma */
 	cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index da2ad5c..165d948 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -482,6 +482,7 @@
 	switch (core->board) {
 	case CX88_BOARD_DNTV_LIVE_DVB_T:
 	case CX88_BOARD_KWORLD_DVB_T:
+	case CX88_BOARD_KWORLD_DVB_T_CX22702:
 		ir_codes = ir_codes_dntv_live_dvb_t;
 		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0x1f;
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index dff3893..e5ee8bc 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -139,6 +139,9 @@
 {
 	int ret, byte;
 
+	if (dev->state & DEV_DISCONNECTED)
+		return(-ENODEV);
+
 	em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
 
 	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -165,6 +168,9 @@
 	u8 val;
 	int ret;
 
+	if (dev->state & DEV_DISCONNECTED)
+		return(-ENODEV);
+
 	em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
 
 	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -195,7 +201,12 @@
 	int ret;
 
 	/*usb_control_msg seems to expect a kmalloced buffer */
-	unsigned char *bufs = kmalloc(len, GFP_KERNEL);
+	unsigned char *bufs;
+
+	if (dev->state & DEV_DISCONNECTED)
+		return(-ENODEV);
+
+	bufs = kmalloc(len, GFP_KERNEL);
 
 	em28xx_regdbg("req=%02x reg=%02x:", req, reg);
 
@@ -212,7 +223,7 @@
 	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      0x0000, reg, bufs, len, HZ);
-	mdelay(5);		/* FIXME: magic number */
+	msleep(5);		/* FIXME: magic number */
 	kfree(bufs);
 	return ret;
 }
@@ -253,7 +264,7 @@
 	if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
 		return ret;
 	else if (((u8) ret) & 0x01) {
-		em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
+		em28xx_warn ("AC97 command still being executed: not handled properly!\n");
 	}
 	return 0;
 }
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 0591a70..6ca8631 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -78,7 +78,7 @@
 		ret = dev->em28xx_read_reg(dev, 0x05);
 		if (ret == 0x80 + len - 1)
 			return len;
-		mdelay(5);
+		msleep(5);
 	}
 	em28xx_warn("i2c write timed out\n");
 	return -EIO;
@@ -138,7 +138,7 @@
 			return -ENODEV;
 		else if (msg == 0x84)
 			return 0;
-		mdelay(5);
+		msleep(5);
 	}
 	return -ENODEV;
 }
@@ -278,9 +278,9 @@
 							   msgs[i].buf,
 							   msgs[i].len,
 							   i == num - 1);
-			if (rc < 0)
-				goto err;
 		}
+		if (rc < 0)
+			goto err;
 		if (i2c_debug>=2)
 			printk("\n");
 	}
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index eea304f..94a14a2 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -6,6 +6,9 @@
 		      Mauro Carvalho Chehab <mchehab@brturbo.com.br>
 		      Sascha Sommer <saschasommer@freenet.de>
 
+	Some parts based on SN9C10x PC Camera Controllers GPL driver made
+		by Luca Risolia <luca.risolia@studio.unibo.it>
+
    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
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index c64718a..5a35d3b 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -136,7 +136,7 @@
 	},
 	[SAA7134_BOARD_FLYVIDEO2000] = {
 		/* "TC Wan" <tcwan@cs.usm.my> */
-		.name           = "LifeView FlyVIDEO2000",
+		.name           = "LifeView/Typhoon FlyVIDEO2000",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
 		.radio_type     = UNSET,
@@ -1884,44 +1884,38 @@
 			.gpio = 0x000,
 		},
 	},
-	[SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS] = {
-		.name		= "Typhoon DVB-T Duo Digital/Analog Cardbus",
+	[SAA7134_BOARD_FLYDVBT_DUO_CARDBUS] = {
+		.name		= "LifeView/Typhoon FlyDVB-T Duo Cardbus",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_PHILIPS_TDA8290,
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.mpeg           = SAA7134_MPEG_DVB,
-		/* .gpiomask       = 0xe000, */
+		.gpiomask	= 0x00200000,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
 			.amux = TV,
-		/*	.gpio = 0x0000,      */
+			.gpio = 0x200000,	/* GPIO21=High for TV input */
 			.tv   = 1,
 		},{
-			.name = name_comp1,	/* Composite signal on S-Video input */
-			.vmux = 0,
-			.amux = LINE2,
-		/*	.gpio = 0x4000,      */
-		},{
-			.name = name_comp2,	/* Composite input */
-			.vmux = 3,
-			.amux = LINE2,
-		/*	.gpio = 0x4000,      */
-		},{
 			.name = name_svideo,	/* S-Video signal on S-Video input */
 			.vmux = 8,
 			.amux = LINE2,
-		/*	.gpio = 0x4000,      */
+		},{
+			.name = name_comp1,	/* Composite signal on S-Video input */
+			.vmux = 0,
+			.amux = LINE2,
+		},{
+			.name = name_comp2,	/* Composite input */
+			.vmux = 3,
+			.amux = LINE2,
 		}},
 		.radio = {
 			.name = name_radio,
-			.amux = LINE2,
-		},
-		.mute = {
-			.name = name_mute,
-			.amux = LINE1,
+			.amux = TV,
+			.gpio = 0x000000,	/* GPIO21=Low for FM radio antenna */
 		},
 	},
 	[SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = {
@@ -2701,6 +2695,12 @@
 		.driver_data  = SAA7134_BOARD_FLYVIDEO2000,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x4e42,		/* Typhoon */
+		.subdevice    = 0x0138,		/* LifeView FlyTV Prime30 OEM */
+		.driver_data  = SAA7134_BOARD_FLYVIDEO2000,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5168,
 		.subdevice    = 0x0212, /* minipci, LR212 */
@@ -2935,7 +2935,7 @@
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5168,
 		.subdevice    = 0x0502,                /* Cardbus version */
-		.driver_data  = SAA7134_BOARD_FLYDVBTDUO,
+		.driver_data  = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -2980,12 +2980,12 @@
 		.subdevice    = 0x1370,        /* cardbus version */
 		.driver_data  = SAA7134_BOARD_ADS_INSTANT_TV,
 
-	},{     /* Typhoon DVB-T Duo Digital/Analog Cardbus */
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-		.subvendor    = 0x4e42,
-		.subdevice    = 0x0502,
-		.driver_data  = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS,
+		.subvendor    = 0x4e42,		/* Typhoon */
+		.subdevice    = 0x0502,		/* LifeView LR502 OEM */
+		.driver_data  = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3206,8 +3206,7 @@
 		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00040000, 0x00040000);
 		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
 		break;
-	case SAA7134_BOARD_FLYDVBTDUO:
-	case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+	case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
 		/* turn the fan on */
 		saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
 		saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 399f995..1a536e86 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -861,7 +861,7 @@
 		dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
 						    &dev->i2c_adap);
 		break;
-	case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+	case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
 		dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
 						    &dev->i2c_adap);
 		break;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index e70eae8..3261d8b 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -185,7 +185,7 @@
 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
 #define SAA7134_BOARD_ADS_INSTANT_TV 58
 #define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
-#define SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS 60
+#define SAA7134_BOARD_FLYDVBT_DUO_CARDBUS 60
 #define SAA7134_BOARD_PHILIPS_TOUGH 61
 #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
 #define SAA7134_BOARD_KWORLD_XPERT 63
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index 54fc330..9d76926 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -2012,7 +2012,6 @@
 {
 	struct saa7146 *saa = pci_get_drvdata(pdev);
 
-	memset(saa, 0, sizeof(*saa));
 	saa->user = 0;
 	/* reset the saa7146 */
 	saawrite(0xffff0000, SAA7146_MC1);
@@ -2062,16 +2061,16 @@
 	}
 	if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) {
 		dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
-		goto errvid;
+		goto errfree;
 	}
 	if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) {
 		dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
-		goto erraud;
+		goto errfree;
 	}
 	/* allocate 81920 byte buffer for clipping */
 	if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
 		dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr);
-		goto errosd;
+		goto errfree;
 	}
 	/* setup clipping registers */
 	saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
@@ -2085,15 +2084,11 @@
 	I2CBusScan(saa);
 
 	return 0;
-errosd:
+errfree:
 	vfree(saa->osdbuf);
-	saa->osdbuf = NULL;
-erraud:
 	vfree(saa->audbuf);
-	saa->audbuf = NULL;
-errvid:
 	vfree(saa->vidbuf);
-	saa->vidbuf = NULL;
+	saa->audbuf = saa->osdbuf = saa->vidbuf = NULL;
 err:
 	return -ENOMEM;
 }
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 5815649..0d54f6c 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -231,7 +231,7 @@
 			   cAudioIF_6_5   |
 			   cVideoIF_38_90 ),
 	},{
-		.std   = V4L2_STD_NTSC_M,
+		.std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
 		.name  = "NTSC-M",
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
@@ -619,6 +619,11 @@
 			tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
 			t->std = V4L2_STD_NTSC_M_JP;
 			break;
+		case 'k':
+		case 'K':
+			tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+			t->std = V4L2_STD_NTSC_M_KR;
+			break;
 		case '-':
 			/* default parameter, do nothing */
 			break;
@@ -876,7 +881,7 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.id             = -1, /* FIXME */
+	.id             = I2C_DRIVERID_TDA9887,
 	.attach_adapter = tda9887_probe,
 	.detach_client  = tda9887_detach,
 	.command        = tda9887_command,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 2995b22..e7ee619 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -216,6 +216,7 @@
 		buffer[3] = 0xa4;
 		i2c_master_send(c,buffer,4);
 		default_tuner_init(c);
+		break;
 	default:
 		default_tuner_init(c);
 		break;
@@ -365,6 +366,11 @@
 			tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
 			t->std = V4L2_STD_NTSC_M_JP;
 			break;
+		case 'k':
+		case 'K':
+			tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+			t->std = V4L2_STD_NTSC_M_KR;
+			break;
 		case '-':
 			/* default parameter, do nothing */
 			break;
@@ -448,7 +454,7 @@
 			printk("%02x ",buffer[i]);
 		printk("\n");
 	}
-	/* TEA5767 autodetection code - only for addr = 0xc0 */
+	/* autodetection code based on the i2c addr */
 	if (!no_autodetect) {
 		switch (addr) {
 		case 0x42:
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 6d03b9b0..c8e5ad0 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -390,6 +390,14 @@
 		chip_write(chip, TDA9840_SW, t);
 }
 
+static int tda9840_checkit(struct CHIPSTATE *chip)
+{
+	int rc;
+	rc = chip_read(chip);
+	/* lower 5 bits should be 0 */
+	return ((rc & 0x1f) == 0) ? 1 : 0;
+}
+
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tda985x                */
 
@@ -1264,6 +1272,7 @@
 		.addr_hi    = I2C_TDA9840 >> 1,
 		.registers  = 5,
 
+		.checkit    = tda9840_checkit,
 		.getmode    = tda9840_getmode,
 		.setmode    = tda9840_setmode,
 		.checkmode  = generic_checkmode,
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index fad9ea0..1864423 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -746,24 +746,27 @@
 
 static inline void tvp5150_reset(struct i2c_client *c)
 {
-	u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom;
+	u8 msb_id, lsb_id, msb_rom, lsb_rom;
 	struct tvp5150 *decoder = i2c_get_clientdata(c);
 
-	type=tvp5150_read(c,TVP5150_AUTOSW_MSK);
 	msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID);
 	lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID);
 	msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER);
 	lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER);
 
-	if (type==0xdc) {
-		ver_656=tvp5150_read(c,TVP5150_REV_SELECT);
-		tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656);
-	} else if (type==0xfc) {
-		tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
+	if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */
+		tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id);
+
+		/* ITU-T BT.656.4 timing */
+		tvp5150_write(c,TVP5150_REV_SELECT,0);
 	} else {
-		tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type);
+		if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */
+			tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
+		} else {
+			tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id);
+			tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom);
+		}
 	}
-	tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom);
 
 	/* Initializes TVP5150 to its default values */
 	tvp5150_write_inittab(c, tvp5150_init_default);
@@ -893,6 +896,17 @@
 		}
 	case DECODER_GET_STATUS:
 		{
+			int *iarg = arg;
+			int status;
+			int res=0;
+			status = tvp5150_read(c, 0x88);
+			if(status&0x08){
+				res |= DECODER_STATUS_COLOR;
+			}
+			if(status&0x04 && status&0x02){
+				res |= DECODER_STATUS_GOOD;
+			}
+			*iarg=res;
 			break;
 		}
 
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index f9e5a23..c08ddac 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -732,7 +732,7 @@
 	    cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid);
 	msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt));
 
-	if (i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT))
+	if (!i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT))
 		status = SUCCESS;
 
 	return status;
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index effa0d7..205bb70 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -301,7 +301,7 @@
 
 config MTD_XIP
 	bool "XIP aware MTD support"
-	depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM
+	depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP
 	default y if XIP_KERNEL
 	help
 	  This allows MTD support to work with flash memory which is also
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index adfba44..2beac55 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -586,6 +586,7 @@
 	dma_addr_t tx_bufs_dma;
 	signed char phys[4];		/* MII device addresses. */
 	char twistie, twist_row, twist_col;	/* Twister tune state. */
+	unsigned int watchdog_fired : 1;
 	unsigned int default_port : 4;	/* Last dev->if_port value. */
 	unsigned int have_thread : 1;
 	spinlock_t lock;
@@ -638,6 +639,7 @@
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
 static void rtl8139_thread (void *_data);
+static void rtl8139_tx_timeout_task(void *_data);
 static struct ethtool_ops rtl8139_ethtool_ops;
 
 /* write MMIO register, with flush */
@@ -1598,13 +1600,14 @@
 {
 	struct net_device *dev = _data;
 	struct rtl8139_private *tp = netdev_priv(dev);
-	unsigned long thr_delay;
+	unsigned long thr_delay = next_tick;
 
-	if (rtnl_shlock_nowait() == 0) {
+	if (tp->watchdog_fired) {
+		tp->watchdog_fired = 0;
+		rtl8139_tx_timeout_task(_data);
+	} else if (rtnl_shlock_nowait() == 0) {
 		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
 		rtnl_unlock ();
-
-		thr_delay = next_tick;
 	} else {
 		/* unlikely race.  mitigate with fast poll. */
 		thr_delay = HZ / 2;
@@ -1631,7 +1634,8 @@
 	if (tp->have_thread) {
 		cancel_rearming_delayed_work(&tp->thread);
 		tp->have_thread = 0;
-	}
+	} else
+		flush_scheduled_work();
 }
 
 static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
@@ -1642,14 +1646,13 @@
 	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
 }
 
-
-static void rtl8139_tx_timeout (struct net_device *dev)
+static void rtl8139_tx_timeout_task (void *_data)
 {
+	struct net_device *dev = _data;
 	struct rtl8139_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
 	int i;
 	u8 tmp8;
-	unsigned long flags;
 
 	printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
 		"media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
@@ -1670,23 +1673,34 @@
 	if (tmp8 & CmdTxEnb)
 		RTL_W8 (ChipCmd, CmdRxEnb);
 
-	spin_lock(&tp->rx_lock);
+	spin_lock_bh(&tp->rx_lock);
 	/* Disable interrupts by clearing the interrupt mask. */
 	RTL_W16 (IntrMask, 0x0000);
 
 	/* Stop a shared interrupt from scavenging while we are. */
-	spin_lock_irqsave (&tp->lock, flags);
+	spin_lock_irq(&tp->lock);
 	rtl8139_tx_clear (tp);
-	spin_unlock_irqrestore (&tp->lock, flags);
+	spin_unlock_irq(&tp->lock);
 
 	/* ...and finally, reset everything */
 	if (netif_running(dev)) {
 		rtl8139_hw_start (dev);
 		netif_wake_queue (dev);
 	}
-	spin_unlock(&tp->rx_lock);
+	spin_unlock_bh(&tp->rx_lock);
 }
 
+static void rtl8139_tx_timeout (struct net_device *dev)
+{
+	struct rtl8139_private *tp = netdev_priv(dev);
+
+	if (!tp->have_thread) {
+		INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
+		schedule_delayed_work(&tp->thread, next_tick);
+	} else
+		tp->watchdog_fired = 1;
+
+}
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 6a6a084..47c72a6 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -4,9 +4,9 @@
 #
 
 menu "Network device support"
+	depends on NET
 
 config NETDEVICES
-	depends on NET
 	default y if UML
 	bool "Network device support"
 	---help---
@@ -24,9 +24,6 @@
 
 	  If unsure, say Y.
 
-# All the following symbols are dependent on NETDEVICES - do not repeat
-# that for each of the symbols.
-if NETDEVICES
 
 config IFB
 	tristate "Intermediate Functional Block support"
@@ -2718,8 +2715,6 @@
 	If you want to log kernel messages over the network, enable this.
 	See <file:Documentation/networking/netconsole.txt> for details.
 
-endif #NETDEVICES
-
 config NETPOLL
 	def_bool NETCONSOLE
 
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 4ff006c..e0f51af 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1145,7 +1145,8 @@
 }
 
 #define BOND_INTERSECT_FEATURES \
-	(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
+	(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
+	NETIF_F_TSO|NETIF_F_UFO)
 
 /* 
  * Compute the common dev->feature set available to all slaves.  Some
@@ -1168,6 +1169,16 @@
 			  NETIF_F_HW_CSUM)))
 		features &= ~NETIF_F_SG;
 
+	/* 
+	 * features will include NETIF_F_TSO (NETIF_F_UFO) iff all 
+	 * slave devices support NETIF_F_TSO (NETIF_F_UFO), which 
+	 * implies that all slaves also support scatter-gather 
+	 * (NETIF_F_SG), which implies that features also includes 
+	 * NETIF_F_SG. So no need to check whether we have an  
+	 * illegal combination of NETIF_F_{TSO,UFO} and 
+	 * !NETIF_F_SG 
+	 */
+
 	features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
 	bond_dev->features = features;
 
@@ -4080,6 +4091,8 @@
 
 static struct ethtool_ops bond_ethtool_ops = {
 	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.get_tso		= ethtool_op_get_tso,
+	.get_ufo		= ethtool_op_get_ufo,
 	.get_sg			= ethtool_op_get_sg,
 	.get_drvinfo		= bond_ethtool_get_drvinfo,
 };
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 32d13da..041bcc5 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -260,7 +260,7 @@
 	char *ifname;
 	int i, res, found, ret = count;
 	struct slave *slave;
-	struct net_device *dev = 0;
+	struct net_device *dev = NULL;
 	struct bonding *bond = to_bond(cd);
 
 	/* Quick sanity check -- is the bond interface up? */
@@ -995,7 +995,7 @@
 			printk(KERN_INFO DRV_NAME
 			       ": %s: Setting primary slave to None.\n",
 			       bond->dev->name);
-			bond->primary_slave = 0;
+			bond->primary_slave = NULL;
 				bond_select_active_slave(bond);
 		} else {
 			printk(KERN_INFO DRV_NAME
@@ -1123,7 +1123,7 @@
 			printk(KERN_INFO DRV_NAME
 			       ": %s: Setting active slave to None.\n",
 			       bond->dev->name);
-			bond->primary_slave = 0;
+			bond->primary_slave = NULL;
 				bond_select_active_slave(bond);
 		} else {
 			printk(KERN_INFO DRV_NAME
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index bf1fd2b..24253c8 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2752,8 +2752,6 @@
 	retval = pci_enable_wake(pdev, 0, 0);
 	if (retval)
 		DPRINTK(PROBE,ERR, "Error clearing wake events\n");
-	if(e100_hw_init(nic))
-		DPRINTK(HW, ERR, "e100_hw_init failed\n");
 
 	netif_device_attach(netdev);
 	if(netif_running(netdev))
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0c18dbd..0e8e3fc 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -199,8 +199,7 @@
 
 	/* get a pointer to the register memory */
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = (struct gfar *)
-		ioremap(r->start, sizeof (struct gfar));
+	priv->regs = ioremap(r->start, sizeof (struct gfar));
 
 	if (NULL == priv->regs) {
 		err = -ENOMEM;
@@ -369,7 +368,7 @@
 	return 0;
 
 register_fail:
-	iounmap((void *) priv->regs);
+	iounmap(priv->regs);
 regs_fail:
 	free_netdev(dev);
 	return err;
@@ -382,7 +381,7 @@
 
 	platform_set_drvdata(pdev, NULL);
 
-	iounmap((void *) priv->regs);
+	iounmap(priv->regs);
 	free_netdev(dev);
 
 	return 0;
@@ -454,8 +453,7 @@
 
 	/* Zero out the rmon mib registers if it has them */
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
-		memset((void *) &(priv->regs->rmon), 0,
-		       sizeof (struct rmon_mib));
+		memset_io(&(priv->regs->rmon), 0, sizeof (struct rmon_mib));
 
 		/* Mask off the CAM interrupts */
 		gfar_write(&priv->regs->rmon.cam1, 0xffffffff);
@@ -477,7 +475,7 @@
 void gfar_halt(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar *regs = priv->regs;
+	struct gfar __iomem *regs = priv->regs;
 	u32 tempval;
 
 	/* Mask all interrupts */
@@ -507,7 +505,7 @@
 void stop_gfar(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar *regs = priv->regs;
+	struct gfar __iomem *regs = priv->regs;
 	unsigned long flags;
 
 	phy_stop(priv->phydev);
@@ -590,7 +588,7 @@
 void gfar_start(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar *regs = priv->regs;
+	struct gfar __iomem *regs = priv->regs;
 	u32 tempval;
 
 	/* Enable Rx and Tx in MACCFG1 */
@@ -624,7 +622,7 @@
 	unsigned long vaddr;
 	int i;
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar *regs = priv->regs;
+	struct gfar __iomem *regs = priv->regs;
 	int err = 0;
 	u32 rctrl = 0;
 	u32 attrs = 0;
@@ -1622,7 +1620,7 @@
 static void adjust_link(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar *regs = priv->regs;
+	struct gfar __iomem *regs = priv->regs;
 	unsigned long flags;
 	struct phy_device *phydev = priv->phydev;
 	int new_state = 0;
@@ -1703,7 +1701,7 @@
 {
 	struct dev_mc_list *mc_ptr;
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar *regs = priv->regs;
+	struct gfar __iomem *regs = priv->regs;
 	u32 tempval;
 
 	if(dev->flags & IFF_PROMISC) {
@@ -1842,7 +1840,7 @@
 	int idx;
 	char tmpbuf[MAC_ADDR_LEN];
 	u32 tempval;
-	u32 *macptr = &priv->regs->macstnaddr1;
+	u32 __iomem *macptr = &priv->regs->macstnaddr1;
 
 	macptr += num*2;
 
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index cb9d66ac..d37d540 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -682,8 +682,8 @@
 	struct rxbd8 *cur_rx;           /* Next free rx ring entry */
 	struct txbd8 *cur_tx;	        /* Next free ring entry */
 	struct txbd8 *dirty_tx;		/* The Ring entry to be freed. */
-	struct gfar *regs;	/* Pointer to the GFAR memory mapped Registers */
-	u32 *hash_regs[16];
+	struct gfar __iomem *regs;	/* Pointer to the GFAR memory mapped Registers */
+	u32 __iomem *hash_regs[16];
 	int hash_width;
 	struct net_device_stats stats; /* linux network statistics */
 	struct gfar_extra_stats extra_stats;
@@ -718,14 +718,14 @@
 	uint32_t msg_enable;
 };
 
-static inline u32 gfar_read(volatile unsigned *addr)
+static inline u32 gfar_read(volatile unsigned __iomem *addr)
 {
 	u32 val;
 	val = in_be32(addr);
 	return val;
 }
 
-static inline void gfar_write(volatile unsigned *addr, u32 val)
+static inline void gfar_write(volatile unsigned __iomem *addr, u32 val)
 {
 	out_be32(addr, val);
 }
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 765e810..5de7b2e 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -144,11 +144,11 @@
 	u64 *extra = (u64 *) & priv->extra_stats;
 
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
-		u32 *rmon = (u32 *) & priv->regs->rmon;
+		u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon;
 		struct gfar_stats *stats = (struct gfar_stats *) buf;
 
 		for (i = 0; i < GFAR_RMON_LEN; i++)
-			stats->rmon[i] = (u64) (rmon[i]);
+			stats->rmon[i] = (u64) gfar_read(&rmon[i]);
 
 		for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
 			stats->extra[i] = extra[i];
@@ -221,11 +221,11 @@
 {
 	int i;
 	struct gfar_private *priv = netdev_priv(dev);
-	u32 *theregs = (u32 *) priv->regs;
+	u32 __iomem *theregs = (u32 __iomem *) priv->regs;
 	u32 *buf = (u32 *) regbuf;
 
 	for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
-		buf[i] = theregs[i];
+		buf[i] = gfar_read(&theregs[i]);
 }
 
 /* Convert microseconds to ethernet clock ticks, which changes
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 74e52fc..c6b7255 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -50,7 +50,7 @@
  * All PHY configuration is done through the TSEC1 MIIM regs */
 int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
 {
-	struct gfar_mii *regs = bus->priv;
+	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
 
 	/* Set the PHY address and the register address we want to write */
 	gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
@@ -70,7 +70,7 @@
  * configuration has to be done through the TSEC1 MIIM regs */
 int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
-	struct gfar_mii *regs = bus->priv;
+	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
 	u16 value;
 
 	/* Set the PHY address and the register address we want to read */
@@ -94,7 +94,7 @@
 /* Reset the MIIM registers, and wait for the bus to free */
 int gfar_mdio_reset(struct mii_bus *bus)
 {
-	struct gfar_mii *regs = bus->priv;
+	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
 	unsigned int timeout = PHY_INIT_TIMEOUT;
 
 	spin_lock_bh(&bus->mdio_lock);
@@ -126,7 +126,7 @@
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct gianfar_mdio_data *pdata;
-	struct gfar_mii *regs;
+	struct gfar_mii __iomem *regs;
 	struct mii_bus *new_bus;
 	struct resource *r;
 	int err = 0;
@@ -155,15 +155,14 @@
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 	/* Set the PHY base address */
-	regs = (struct gfar_mii *) ioremap(r->start,
-			sizeof (struct gfar_mii));
+	regs = ioremap(r->start, sizeof (struct gfar_mii));
 
 	if (NULL == regs) {
 		err = -ENOMEM;
 		goto reg_map_fail;
 	}
 
-	new_bus->priv = regs;
+	new_bus->priv = (void __force *)regs;
 
 	new_bus->irq = pdata->irq;
 
@@ -181,7 +180,7 @@
 	return 0;
 
 bus_register_fail:
-	iounmap((void *) regs);
+	iounmap(regs);
 reg_map_fail:
 	kfree(new_bus);
 
@@ -197,7 +196,7 @@
 
 	dev_set_drvdata(dev, NULL);
 
-	iounmap((void *) (&bus->priv));
+	iounmap((void __iomem *)bus->priv);
 	bus->priv = NULL;
 	kfree(bus);
 
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
index 3b1bef1..77411a0 100644
--- a/drivers/net/hamradio/baycom_par.c
+++ b/drivers/net/hamradio/baycom_par.c
@@ -86,7 +86,6 @@
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
 
-#include <asm/bug.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 7ef4b04..c0998ef 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -32,6 +32,8 @@
  */
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/etherdevice.h>
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 1c6d328..0245e40 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1610,6 +1610,8 @@
 		}
 		else if (!pskb_may_pull(skb, skb->len))
 			goto err;
+		else
+			skb->ip_summed = CHECKSUM_NONE;
 
 		len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2);
 		if (len <= 0) {
@@ -1690,6 +1692,7 @@
 			kfree_skb(skb);
 		} else {
 			skb_pull(skb, 2);	/* chop off protocol */
+			skb_postpull_rcsum(skb, skb->data - 2, 2);
 			skb->dev = ppp->dev;
 			skb->protocol = htons(npindex_to_ethertype[npi]);
 			skb->mac.raw = skb->data;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2e1bed15..6e10184 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -484,13 +484,12 @@
 	int i;
 
 	RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
-	udelay(1000);
 
-	for (i = 2000; i > 0; i--) {
+	for (i = 20; i > 0; i--) {
 		/* Check if the RTL8169 has completed writing to the specified MII register */
 		if (!(RTL_R32(PHYAR) & 0x80000000)) 
 			break;
-		udelay(100);
+		udelay(25);
 	}
 }
 
@@ -499,15 +498,14 @@
 	int i, value = -1;
 
 	RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
-	udelay(1000);
 
-	for (i = 2000; i > 0; i--) {
+	for (i = 20; i > 0; i--) {
 		/* Check if the RTL8169 has completed retrieving data from the specified MII register */
 		if (RTL_R32(PHYAR) & 0x80000000) {
 			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
 			break;
 		}
-		udelay(100);
+		udelay(25);
 	}
 	return value;
 }
@@ -677,6 +675,9 @@
 
 		if (duplex == DUPLEX_HALF)
 			auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
+
+		if (duplex == DUPLEX_FULL)
+			auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
 	}
 
 	tp->phy_auto_nego_reg = auto_nego;
diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h
index 4233ea5..5032394 100644
--- a/drivers/net/sis900.h
+++ b/drivers/net/sis900.h
@@ -33,7 +33,6 @@
         rxcfg=0x34,             //Receive Configuration Register
         flctrl=0x38,            //Flow Control Register
         rxlen=0x3c,             //Receive Packet Length Register
-        cfgpmcsr=0x44,          //Configuration Power Management Control/Status Register
         rfcr=0x48,              //Receive Filter Control Register
         rfdr=0x4C,              //Receive Filter Data Register
         pmctrl=0xB0,            //Power Management Control Register
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f8b973a..cae2edf 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -23,12 +23,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/*
- * TOTEST
- *	- speed setting
- *	- suspend/resume
- */
-
 #include <linux/config.h>
 #include <linux/crc32.h>
 #include <linux/kernel.h>
@@ -57,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"0.13"
+#define DRV_VERSION		"0.15"
 #define PFX			DRV_NAME " "
 
 /*
@@ -102,6 +96,10 @@
 module_param(copybreak, int, 0);
 MODULE_PARM_DESC(copybreak, "Receive copy threshold");
 
+static int disable_msi = 0;
+module_param(disable_msi, int, 0);
+MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
+
 static const struct pci_device_id sky2_id_table[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
@@ -198,7 +196,7 @@
 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 
 	pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control);
-	vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+	vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
 		(power_control & PCI_PM_CAP_PME_D3cold);
 
 	pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control);
@@ -1834,6 +1832,8 @@
 	u16 hwidx;
 	u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
 
+	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+
 	hwidx = sky2_read16(hw, STAT_PUT_IDX);
 	BUG_ON(hwidx >= STATUS_RING_SIZE);
 	rmb();
@@ -1913,12 +1913,10 @@
 	}
 
 exit_loop:
-	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
 	sky2_tx_check(hw, 0, tx_done[0]);
 	sky2_tx_check(hw, 1, tx_done[1]);
 
-	if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) {
+	if (likely(work_done < to_do)) {
 		/* need to restart TX timer */
 		if (is_ec_a1(hw)) {
 			sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
@@ -2141,14 +2139,12 @@
 
 static int sky2_reset(struct sky2_hw *hw)
 {
-	u32 ctst;
 	u16 status;
 	u8 t8, pmd_type;
-	int i;
-
-	ctst = sky2_read32(hw, B0_CTST);
+	int i, err;
 
 	sky2_write8(hw, B0_CTST, CS_RST_CLR);
+
 	hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
 	if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
 		printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
@@ -2156,12 +2152,6 @@
 		return -EOPNOTSUPP;
 	}
 
-	/* ring for status responses */
-	hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
-					 &hw->st_dma);
-	if (!hw->st_le)
-		return -ENOMEM;
-
 	/* disable ASF */
 	if (hw->chip_id <= CHIP_ID_YUKON_EC) {
 		sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -2173,19 +2163,24 @@
 	sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
 	/* clear PCI errors, if any */
-	pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+	err = pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+	if (err)
+		goto pci_err;
+
 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-	pci_write_config_word(hw->pdev, PCI_STATUS,
-			      status | PCI_STATUS_ERROR_BITS);
+	err = pci_write_config_word(hw->pdev, PCI_STATUS,
+				    status | PCI_STATUS_ERROR_BITS);
+	if (err)
+		goto pci_err;
 
 	sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
 	/* clear any PEX errors */
-	if (is_pciex(hw)) {
-		u16 lstat;
-		pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
-				       0xffffffffUL);
-		pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat);
+	if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) {
+		err = pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+						 0xffffffffUL);
+		if (err)
+			goto pci_err;
 	}
 
 	pmd_type = sky2_read8(hw, B2_PMD_TYP);
@@ -2297,6 +2292,14 @@
 	sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
 
 	return 0;
+
+pci_err:
+	/* This is to catch a BIOS bug workaround where
+	 * mmconfig table doesn't have other buses.
+	 */
+	printk(KERN_ERR PFX "%s: can't access PCI config space\n",
+	       pci_name(hw->pdev));
+	return err;
 }
 
 static u32 sky2_supported_modes(const struct sky2_hw *hw)
@@ -2551,19 +2554,24 @@
 static int sky2_set_mac_address(struct net_device *dev, void *p)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
-	struct sockaddr *addr = p;
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	const struct sockaddr *addr = p;
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-	memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8,
+	memcpy_toio(hw->regs + B2_MAC_1 + port * 8,
 		    dev->dev_addr, ETH_ALEN);
-	memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8,
+	memcpy_toio(hw->regs + B2_MAC_2 + port * 8,
 		    dev->dev_addr, ETH_ALEN);
 
-	if (netif_running(dev))
-		sky2_phy_reinit(sky2);
+	/* virtual address for data */
+	gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+
+	/* physical address: used for pause frames */
+	gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
 
 	return 0;
 }
@@ -2843,7 +2851,7 @@
 	if (ecmd->rx_coalesce_usecs_irq == 0)
 		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
 	else {
-		sky2_write32(hw, STAT_TX_TIMER_INI,
+		sky2_write32(hw, STAT_ISR_TIMER_INI,
 			     sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
 		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
 	}
@@ -3055,6 +3063,61 @@
 		       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 }
 
+/* Handle software interrupt used during MSI test */
+static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id,
+					    struct pt_regs *regs)
+{
+	struct sky2_hw *hw = dev_id;
+	u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
+
+	if (status == 0)
+		return IRQ_NONE;
+
+	if (status & Y2_IS_IRQ_SW) {
+		sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
+		hw->msi = 1;
+	}
+	sky2_write32(hw, B0_Y2_SP_ICR, 2);
+
+	sky2_read32(hw, B0_IMSK);
+	return IRQ_HANDLED;
+}
+
+/* Test interrupt path by forcing a a software IRQ */
+static int __devinit sky2_test_msi(struct sky2_hw *hw)
+{
+	struct pci_dev *pdev = hw->pdev;
+	int i, err;
+
+	sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
+
+	err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw);
+	if (err) {
+		printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+		       pci_name(pdev), pdev->irq);
+		return err;
+	}
+
+	sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
+	wmb();
+
+	for (i = 0; i < 10; i++) {
+		barrier();
+		if (hw->msi)
+			goto found;
+		mdelay(1);
+	}
+
+	err = -EOPNOTSUPP;
+	sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
+ found:
+	sky2_write32(hw, B0_IMSK, 0);
+
+	free_irq(pdev->irq, hw);
+
+	return err;
+}
+
 static int __devinit sky2_probe(struct pci_dev *pdev,
 				const struct pci_device_id *ent)
 {
@@ -3135,6 +3198,12 @@
 	}
 	hw->pm_cap = pm_cap;
 
+	/* ring for status responses */
+	hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
+					 &hw->st_dma);
+	if (!hw->st_le)
+		goto err_out_iounmap;
+
 	err = sky2_reset(hw);
 	if (err)
 		goto err_out_iounmap;
@@ -3169,7 +3238,22 @@
 		}
 	}
 
-	err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
+	if (!disable_msi && pci_enable_msi(pdev) == 0) {
+		err = sky2_test_msi(hw);
+		if (err == -EOPNOTSUPP) {
+			/* MSI test failed, go back to INTx mode */
+			printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
+			       "switching to INTx mode. Please report this failure to "
+			       "the PCI maintainer and include system chipset information.\n",
+			       pci_name(pdev));
+			pci_disable_msi(pdev);
+		}
+		else if (err)
+			goto err_out_unregister;
+	}
+
+	err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
+			  DRV_NAME, hw);
 	if (err) {
 		printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
 		       pci_name(pdev), pdev->irq);
@@ -3184,6 +3268,8 @@
 	return 0;
 
 err_out_unregister:
+	if (hw->msi)
+		pci_disable_msi(pdev);
 	if (dev1) {
 		unregister_netdev(dev1);
 		free_netdev(dev1);
@@ -3226,6 +3312,8 @@
 	sky2_read8(hw, B0_CTST);
 
 	free_irq(pdev->irq, hw);
+	if (hw->msi)
+		pci_disable_msi(pdev);
 	pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
@@ -3263,25 +3351,33 @@
 static int sky2_resume(struct pci_dev *pdev)
 {
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
-	int i;
+	int i, err;
 
 	pci_restore_state(pdev);
 	pci_enable_wake(pdev, PCI_D0, 0);
-	sky2_set_power_state(hw, PCI_D0);
+	err = sky2_set_power_state(hw, PCI_D0);
+	if (err)
+		goto out;
 
-	sky2_reset(hw);
+	err = sky2_reset(hw);
+	if (err)
+		goto out;
 
 	for (i = 0; i < 2; i++) {
 		struct net_device *dev = hw->dev[i];
-		if (dev) {
-			if (netif_running(dev)) {
-				netif_device_attach(dev);
-				if (sky2_up(dev))
-					dev_close(dev);
+		if (dev && netif_running(dev)) {
+			netif_device_attach(dev);
+			err = sky2_up(dev);
+			if (err) {
+				printk(KERN_ERR PFX "%s: could not up: %d\n",
+				       dev->name, err);
+				dev_close(dev);
+				break;
 			}
 		}
 	}
-	return 0;
+out:
+	return err;
 }
 #endif
 
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 9551892..fd12c28 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1841,6 +1841,7 @@
 	struct net_device    *dev[2];
 
 	int		     pm_cap;
+	int		     msi;
 	u8	     	     chip_id;
 	u8		     chip_rev;
 	u8		     copper;
@@ -1867,14 +1868,6 @@
 	return readb(hw->regs + reg);
 }
 
-/* This should probably go away, bus based tweeks suck */
-static inline int is_pciex(const struct sky2_hw *hw)
-{
-	u32 status;
-	pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status);
-	return (status & PCI_OS_PCI_X) == 0;
-}
-
 static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val)
 {
 	writel(val, hw->regs + reg);
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 9839816..238e9c7 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -214,7 +214,7 @@
 /* For module input parameter */
 static int debug;
 static u32 cr6set;
-static unsigned char mode = 8;
+static int mode = 8;
 
 /* function declaration ------------------------------------- */
 static int uli526x_open(struct net_device *);
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 2f61a47..1ff5de0 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -1943,7 +1943,7 @@
 					(++i%TX_RING_SIZE)*sizeof(*tx_fd));
 	} while (i < TX_RING_SIZE);
 
-	if (dscc4_init_dummy_skb(dpriv) < 0)
+	if (!dscc4_init_dummy_skb(dpriv))
 		goto err_free_dma_tx;
 
 	memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE);
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index 8dea07b..eba8e5c 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -29,7 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/hdlc.h>
 #include <linux/pci.h>
-#include <asm/delay.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 #include "hd64572.h"
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 9c1e106..9d3b51c 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -27,8 +27,8 @@
 #include <linux/hdlc.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 #include <asm/io.h>
-#include <asm/delay.h>
 
 #include "wanxl.h"
 
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index c5cd61c..e5bb9f5 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -748,7 +748,7 @@
 	if (essid->length) {
 		dwrq->flags = 1;	/* set ESSID to ON for Wireless Extensions */
 		/* if it is to big, trunk it */
-		dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length);
+		dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length);
 	} else {
 		dwrq->flags = 0;
 		dwrq->length = 0;
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 38d6d00..014cc8d 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -38,10 +38,10 @@
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <asm/semaphore.h>
-#include <asm/delay.h>
 
 #include "aacraid.h"
 
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 311a412..93edaa8 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -537,9 +537,9 @@
 	free_irq(fp->intr, fp);
 
 	if (fp->regs)
-		iounmap((void *) fp->regs);
+		iounmap(fp->regs);
 	if (fp->dma)
-		iounmap((void *) fp->dma);
+		iounmap(fp->dma);
 	kfree(fp->dma_cmd_space);
 
 	scsi_host_put(host);
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 245ca99..c551bb8 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -1245,7 +1245,7 @@
 	if (error)
 		goto cleanup_sysctl;
 
-	for (i = 0; i < NR_CPUS; i++)
+	for_each_cpu(i)
 		INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));
 
 	devfs_mk_dir("scsi");
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 59a1c9d..723f7ac 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -463,7 +463,7 @@
 }
 
 static void*
-mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
+mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
 {
 	struct mempool_zone *zone = pool_data;
 
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7d07000..2a54753 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1679,7 +1679,7 @@
 sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
 {
 	int sg_bufflen = tablesize * sizeof(struct scatterlist);
-	unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
+	gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
 	/*
 	 * TODO: test without low_dma, we should not need it since
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 8cbf0fc..7f0f35a 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -332,7 +332,7 @@
 		 * Make sure that we do not overflow the buffer
 		 */
 		if (tty_request_buffer_room(tty, 1) == 0) {
-			schedule_work(&tty->flip.work);
+			tty_schedule_flip(tty);
 			return;
 		}
 
@@ -353,7 +353,7 @@
 	} while((rx = uart->urx.w) & URX_DATA_READY);
 #endif
 
-	schedule_work(&tty->flip.work);
+	tty_schedule_flip(tty);
 
 clear_and_exit:
 	return;
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index 60f5a5d..9843ae3 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -509,7 +509,7 @@
 
 	info->rx_cur = (QUICC_BD *)bdp;
 
-	schedule_work(&tty->flip.work);
+	tty_schedule_flip(tty);
 }
 
 static _INLINE_ void receive_break(ser_info_t *info)
@@ -521,7 +521,7 @@
 	 * the break.  If not, we exit now, losing the break.  FIXME
 	 */
 	tty_insert_flip_char(tty, 0, TTY_BREAK);
-	schedule_work(&tty->flip.work);
+	tty_schedule_flip(tty);
 }
 
 static _INLINE_ void transmit_chars(ser_info_t *info)
diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h
index 07d0dd8..7c3ec24 100644
--- a/drivers/serial/m32r_sio.h
+++ b/drivers/serial/m32r_sio.h
@@ -37,7 +37,7 @@
 	unsigned int irq;
 	unsigned int flags;
 	unsigned char io_type;
-	unsigned char *iomem_base;
+	unsigned char __iomem *iomem_base;
 	unsigned short iomem_reg_shift;
 };
 
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 0ef648f..8cbbb95 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -57,20 +57,16 @@
  *	keep going.  Perhaps one day the cflag settings for the
  *	console can be used instead.
  */
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
-    defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
-#define	CONSOLE_BAUD_RATE	19200
-#define	DEFAULT_CBAUD		B19200
-#endif
-
 #if defined(CONFIG_HW_FEITH)
 #define	CONSOLE_BAUD_RATE	38400
 #define	DEFAULT_CBAUD		B38400
-#endif
-
-#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
+#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
 #define CONSOLE_BAUD_RATE 	115200
 #define DEFAULT_CBAUD		B115200
+#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+      defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#define	CONSOLE_BAUD_RATE	19200
+#define	DEFAULT_CBAUD		B19200
 #endif
 
 #ifndef CONSOLE_BAUD_RATE
@@ -350,7 +346,7 @@
 		}
 		tty_insert_flip_char(tty, ch, flag);
 	}
-	tty_flip_buffer_push(tty);
+	tty_schedule_flip(tty);
 	return;
 }
 
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 0a2dd6c..7410e09 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -161,7 +161,11 @@
 
 /* we can support 3 uarts, but not always use them */
 
+#ifdef CONFIG_CPU_S3C2400
+#define NR_PORTS (2)
+#else
 #define NR_PORTS (3)
+#endif
 
 /* port irq numbers */
 
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index c70ae81..12357e1 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -38,10 +38,10 @@
 
 static int nic_wait(struct ioc3_driver_data *idd)
 {
-	volatile unsigned mcr;
+	unsigned mcr;
 
         do {
-                mcr = (volatile unsigned)idd->vma->mcr;
+                mcr = readl(&idd->vma->mcr);
         } while (!(mcr & 2));
 
         return mcr & 1;
@@ -53,7 +53,7 @@
 	unsigned long flags;
 
 	local_irq_save(flags);
-	idd->vma->mcr = mcr_pack(500, 65);
+	writel(mcr_pack(500, 65), &idd->vma->mcr);
 	presence = nic_wait(idd);
 	local_irq_restore(flags);
 
@@ -68,7 +68,7 @@
 	unsigned long flags;
 
 	local_irq_save(flags);
-	idd->vma->mcr = mcr_pack(6, 13);
+	writel(mcr_pack(6, 13), &idd->vma->mcr);
 	result = nic_wait(idd);
 	local_irq_restore(flags);
 
@@ -80,9 +80,9 @@
 static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit)
 {
 	if (bit)
-		idd->vma->mcr = mcr_pack(6, 110);
+		writel(mcr_pack(6, 110), &idd->vma->mcr);
 	else
-		idd->vma->mcr = mcr_pack(80, 30);
+		writel(mcr_pack(80, 30), &idd->vma->mcr);
 
 	nic_wait(idd);
 }
@@ -337,7 +337,7 @@
         int save = 0, loops = 3;
         unsigned long first, addr;
 
-        idd->vma->gpcr_s = GPCR_MLAN_EN;
+        writel(GPCR_MLAN_EN, &idd->vma->gpcr_s);
 
         while(loops>0) {
                 idd->nic_part[0] = 0;
@@ -408,7 +408,7 @@
 
 	read_lock_irqsave(&ioc3_submodules_lock, flags);
 
-	if(idd->dual_irq && idd->vma->eisr) {
+	if(idd->dual_irq && readb(&idd->vma->eisr)) {
 		/* send Ethernet IRQ to the driver */
 		if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
 						ioc3_ethernet->intr) {
@@ -682,7 +682,7 @@
 	idd->id = ioc3_counter++;
 	up_write(&ioc3_devices_rwsem);
 
-	idd->gpdr_shadow = idd->vma->gpdr;
+	idd->gpdr_shadow = readl(&idd->vma->gpdr);
 
 	/* Read IOC3 NIC contents */
 	probe_nic(idd);
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b77dbd6..7a75fae 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -75,16 +75,6 @@
 	  inexpensive battery powered microcontroller evaluation board.
 	  This same cable can be used to flash new firmware.
 
-config SPI_BUTTERFLY
-	tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
-	depends on SPI_MASTER && PARPORT && EXPERIMENTAL
-	select SPI_BITBANG
-	help
-	  This uses a custom parallel port cable to connect to an AVR
-	  Butterfly <http://www.atmel.com/products/avr/butterfly>, an
-	  inexpensive battery powered microcontroller evaluation board.
-	  This same cable can be used to flash new firmware.
-
 #
 # Add new SPI master controllers in alphabetical order above this line
 #
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
index 79a3c59..ff9e5fa 100644
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -163,21 +163,20 @@
 	struct butterfly	*pp = spidev_to_pp(spi);
 
 	/* set default clock polarity */
-	if (value)
+	if (value != BITBANG_CS_INACTIVE)
 		setsck(spi, spi->mode & SPI_CPOL);
 
 	/* no chipselect on this USI link config */
 	if (is_usidev(spi))
 		return;
 
-	/* here, value == "activate or not" */
-
-	/* most PARPORT_CONTROL_* bits are negated */
+	/* here, value == "activate or not";
+	 * most PARPORT_CONTROL_* bits are negated, so we must
+	 * morph it to value == "bit value to write in control register"
+	 */
 	if (spi_cs_bit == PARPORT_CONTROL_INIT)
 		value = !value;
 
-	/* here, value == "bit value to write in control register"  */
-
 	parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0);
 }
 
@@ -202,7 +201,9 @@
 
 /* override default partitioning with cmdlinepart */
 static struct mtd_partition partitions[] = { {
-	/* JFFS2 wants partitions of 4*N blocks for this device ... */
+	/* JFFS2 wants partitions of 4*N blocks for this device,
+	 * so sectors 0 and 1 can't be partitions by themselves.
+	 */
 
 	/* sector 0 = 8 pages * 264 bytes/page (1 block)
 	 * sector 1 = 248 pages * 264 bytes/page
@@ -316,8 +317,9 @@
 	if (status < 0)
 		goto clean2;
 
-	/* Bus 1 lets us talk to at45db041b (firmware disables AVR)
-	 * or AVR (firmware resets at45, acts as spi slave)
+	/* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR
+	 * (firmware resets at45, acts as spi slave) or neither (we ignore
+	 * both, AVR uses AT45).  Here we expect firmware for the first option.
 	 */
 	pp->info[0].max_speed_hz = 15 * 1000 * 1000;
 	strcpy(pp->info[0].modalias, "mtd_dataflash");
@@ -330,7 +332,9 @@
 				pp->dataflash->dev.bus_id);
 
 #ifdef	HAVE_USI
-	/* even more custom AVR firmware */
+	/* Bus 2 is only for talking to the AVR, and it can work no
+	 * matter who masters bus 1; needs appropriate AVR firmware.
+	 */
 	pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
 	strcpy(pp->info[1].modalias, "butterfly");
 	// pp->info[1].platform_data = ... TBD ... ;
@@ -378,13 +382,8 @@
 	pp = butterfly;
 	butterfly = NULL;
 
-#ifdef	HAVE_USI
-	spi_unregister_device(pp->butterfly);
-	pp->butterfly = NULL;
-#endif
-	spi_unregister_device(pp->dataflash);
-	pp->dataflash = NULL;
-
+	/* stop() unregisters child devices too */
+	pdev = to_platform_device(pp->bitbang.master->cdev.dev);
 	status = spi_bitbang_stop(&pp->bitbang);
 
 	/* turn off VCC */
@@ -394,8 +393,6 @@
 	parport_release(pp->pd);
 	parport_unregister_device(pp->pd);
 
-	pdev = to_platform_device(pp->bitbang.master->cdev.dev);
-
 	(void) spi_master_put(pp->bitbang.master);
 
 	platform_device_unregister(pdev);
@@ -420,4 +417,5 @@
 }
 module_exit(butterfly_exit);
 
+MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly");
 MODULE_LICENSE("GPL");
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index a0e5af6..4a51e56 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
-#include <asm/bug.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/paccess.h>
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 076462c..dce9d98 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -378,7 +378,7 @@
 
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(usb_match_id);
+EXPORT_SYMBOL(usb_match_id);
 
 int usb_device_match(struct device *dev, struct device_driver *drv)
 {
@@ -446,7 +446,7 @@
 
 	return retval;
 }
-EXPORT_SYMBOL_GPL(usb_register_driver);
+EXPORT_SYMBOL(usb_register_driver);
 
 /**
  * usb_deregister - unregister a USB driver
@@ -469,4 +469,4 @@
 
 	usbfs_update_special();
 }
-EXPORT_SYMBOL_GPL(usb_deregister);
+EXPORT_SYMBOL(usb_deregister);
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 9d5015e..bd39bbd 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -13,7 +13,6 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
-#include <asm/bug.h>
 
 static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
 {
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 68c6906..9e32485 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -13,7 +13,6 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
-#include <asm/bug.h>
 
 static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
 {
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index f3927b6..f5361cd 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include <asm/bug.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 25148de..eeeac92 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include <asm/bug.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 5dd0207..057e602 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -931,8 +931,8 @@
 static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	int err, i;
-	sg_req_info_t *r;
-	struct compat_sg_req_info *o = (struct compat_sg_req_info *)arg;
+	sg_req_info_t __user *r;
+	struct compat_sg_req_info __user *o = (void __user *)arg;
 	r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
 	err = sys_ioctl(fd,cmd,(unsigned long)r);
 	if (err < 0)
@@ -2739,8 +2739,8 @@
 static int
 lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct compat_timeval *tc = (struct compat_timeval *)arg;
-	struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval));
+	struct compat_timeval __user *tc = (struct compat_timeval __user *)arg;
+	struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval));
 	struct timeval ts;
 	if (get_user(ts.tv_sec, &tc->tv_sec) ||
 	    get_user(ts.tv_usec, &tc->tv_usec) ||
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index efc97d9..d575452 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -56,7 +56,7 @@
 DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
 
 /**
- * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write an unsigned 8 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
@@ -98,7 +98,7 @@
 DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
 
 /**
- * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write an unsigned 16 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
@@ -140,7 +140,7 @@
 DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
 
 /**
- * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write an unsigned 32 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
diff --git a/fs/file.c b/fs/file.c
index fd066b2..cea7cbe 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -379,7 +379,6 @@
 void __init files_defer_init(void)
 {
 	int i;
-	/* Really early - can't use for_each_cpu */
-	for (i = 0; i < NR_CPUS; i++)
+	for_each_cpu(i)
 		fdtable_defer_list_init(i);
 }
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 4526da8..f556a0d 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -120,9 +120,9 @@
 	return do_get_request(fc);
 }
 
+/* Must be called with fuse_lock held */
 static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
 {
-	spin_lock(&fuse_lock);
 	if (req->preallocated) {
 		atomic_dec(&fc->num_waiting);
 		list_add(&req->list, &fc->unused_list);
@@ -134,11 +134,19 @@
 		fc->outstanding_debt--;
 	else
 		up(&fc->outstanding_sem);
-	spin_unlock(&fuse_lock);
 }
 
 void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
 {
+	if (atomic_dec_and_test(&req->count)) {
+		spin_lock(&fuse_lock);
+		fuse_putback_request(fc, req);
+		spin_unlock(&fuse_lock);
+	}
+}
+
+static void fuse_put_request_locked(struct fuse_conn *fc, struct fuse_req *req)
+{
 	if (atomic_dec_and_test(&req->count))
 		fuse_putback_request(fc, req);
 }
@@ -163,26 +171,36 @@
  * still waiting), the 'end' callback is called if given, else the
  * reference to the request is released
  *
+ * Releasing extra reference for foreground requests must be done
+ * within the same locked region as setting state to finished.  This
+ * is because fuse_reset_request() may be called after request is
+ * finished and it must be the sole possessor.  If request is
+ * interrupted and put in the background, it will return with an error
+ * and hence never be reset and reused.
+ *
  * Called with fuse_lock, unlocks it
  */
 static void request_end(struct fuse_conn *fc, struct fuse_req *req)
 {
-	void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
-	req->end = NULL;
 	list_del(&req->list);
 	req->state = FUSE_REQ_FINISHED;
-	spin_unlock(&fuse_lock);
-	if (req->background) {
+	if (!req->background) {
+		wake_up(&req->waitq);
+		fuse_put_request_locked(fc, req);
+		spin_unlock(&fuse_lock);
+	} else {
+		void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
+		req->end = NULL;
+		spin_unlock(&fuse_lock);
 		down_read(&fc->sbput_sem);
 		if (fc->mounted)
 			fuse_release_background(req);
 		up_read(&fc->sbput_sem);
+		if (end)
+			end(fc, req);
+		else
+			fuse_put_request(fc, req);
 	}
-	wake_up(&req->waitq);
-	if (end)
-		end(fc, req);
-	else
-		fuse_put_request(fc, req);
 }
 
 /*
diff --git a/fs/inotify.c b/fs/inotify.c
index 878ccca..3041503 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -967,7 +967,7 @@
 		mask_add = 1;
 
 	/* don't let user-space set invalid bits: we don't want flags set */
-	mask &= IN_ALL_EVENTS;
+	mask &= IN_ALL_EVENTS | IN_ONESHOT;
 	if (unlikely(!mask)) {
 		ret = -EINVAL;
 		goto out;
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 429f4b2..ca91797 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1308,6 +1308,7 @@
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
 	int old_handle_count, err;
+	pid_t pid;
 
 	J_ASSERT(transaction->t_updates > 0);
 	J_ASSERT(journal_current_handle() == handle);
@@ -1333,8 +1334,15 @@
 	 * It doesn't cost much - we're about to run a commit and sleep
 	 * on IO anyway.  Speeds up many-threaded, many-dir operations
 	 * by 30x or more...
+	 *
+	 * But don't do this if this process was the most recent one to
+	 * perform a synchronous write.  We do this to detect the case where a
+	 * single process is doing a stream of sync writes.  No point in waiting
+	 * for joiners in that case.
 	 */
-	if (handle->h_sync) {
+	pid = current->pid;
+	if (handle->h_sync && journal->j_last_sync_writer != pid) {
+		journal->j_last_sync_writer = pid;
 		do {
 			old_handle_count = transaction->t_handle_count;
 			schedule_timeout_uninterruptible(1);
diff --git a/fs/namei.c b/fs/namei.c
index 7ac9fb4..e28de84 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -790,7 +790,7 @@
 
 	inode = nd->dentry->d_inode;
 	if (nd->depth)
-		lookup_flags = LOOKUP_FOLLOW;
+		lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
 
 	/* At this point we know we have a real path component. */
 	for(;;) {
@@ -885,7 +885,8 @@
 last_with_slashes:
 		lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
 last_component:
-		nd->flags &= ~LOOKUP_CONTINUE;
+		/* Clear LOOKUP_CONTINUE iff it was previously unset */
+		nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
 		if (lookup_flags & LOOKUP_PARENT)
 			goto lookup_parent;
 		if (this.name[0] == '.') switch (this.len) {
@@ -1069,6 +1070,8 @@
 				unsigned int flags, struct nameidata *nd)
 {
 	int retval = 0;
+	int fput_needed;
+	struct file *file;
 
 	nd->last_type = LAST_ROOT; /* if there are only slashes... */
 	nd->flags = flags;
@@ -1090,29 +1093,22 @@
 		nd->mnt = mntget(current->fs->pwdmnt);
 		nd->dentry = dget(current->fs->pwd);
 	} else {
-		struct file *file;
-		int fput_needed;
 		struct dentry *dentry;
 
 		file = fget_light(dfd, &fput_needed);
-		if (!file) {
-			retval = -EBADF;
-			goto out_fail;
-		}
+		retval = -EBADF;
+		if (!file)
+			goto unlock_fail;
 
 		dentry = file->f_dentry;
 
-		if (!S_ISDIR(dentry->d_inode->i_mode)) {
-			retval = -ENOTDIR;
-			fput_light(file, fput_needed);
-			goto out_fail;
-		}
+		retval = -ENOTDIR;
+		if (!S_ISDIR(dentry->d_inode->i_mode))
+			goto fput_unlock_fail;
 
 		retval = file_permission(file, MAY_EXEC);
-		if (retval) {
-			fput_light(file, fput_needed);
-			goto out_fail;
-		}
+		if (retval)
+			goto fput_unlock_fail;
 
 		nd->mnt = mntget(file->f_vfsmnt);
 		nd->dentry = dget(dentry);
@@ -1123,10 +1119,17 @@
 	current->total_link_count = 0;
 	retval = link_path_walk(name, nd);
 out:
-	if (unlikely(current->audit_context
-		     && nd && nd->dentry && nd->dentry->d_inode))
+	if (likely(retval == 0)) {
+		if (unlikely(current->audit_context && nd && nd->dentry &&
+				nd->dentry->d_inode))
 		audit_inode(name, nd->dentry->d_inode, flags);
-out_fail:
+	}
+	return retval;
+
+fput_unlock_fail:
+	fput_light(file, fput_needed);
+unlock_fail:
+	read_unlock(&current->fs->lock);
 	return retval;
 }
 
diff --git a/fs/namespace.c b/fs/namespace.c
index ce97bec..058a448 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -494,7 +494,7 @@
 		p->mnt_namespace = NULL;
 		list_del_init(&p->mnt_child);
 		if (p->mnt_parent != p)
-			mnt->mnt_mountpoint->d_mounted--;
+			p->mnt_mountpoint->d_mounted--;
 		change_mnt_propagation(p, MS_PRIVATE);
 	}
 }
@@ -1325,27 +1325,17 @@
 	return retval;
 }
 
-int copy_namespace(int flags, struct task_struct *tsk)
+/*
+ * Allocate a new namespace structure and populate it with contents
+ * copied from the namespace of the passed in task structure.
+ */
+struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
 {
 	struct namespace *namespace = tsk->namespace;
 	struct namespace *new_ns;
 	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
-	struct fs_struct *fs = tsk->fs;
 	struct vfsmount *p, *q;
 
-	if (!namespace)
-		return 0;
-
-	get_namespace(namespace);
-
-	if (!(flags & CLONE_NEWNS))
-		return 0;
-
-	if (!capable(CAP_SYS_ADMIN)) {
-		put_namespace(namespace);
-		return -EPERM;
-	}
-
 	new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
 	if (!new_ns)
 		goto out;
@@ -1396,8 +1386,6 @@
 	}
 	up_write(&namespace_sem);
 
-	tsk->namespace = new_ns;
-
 	if (rootmnt)
 		mntput(rootmnt);
 	if (pwdmnt)
@@ -1405,12 +1393,40 @@
 	if (altrootmnt)
 		mntput(altrootmnt);
 
-	put_namespace(namespace);
-	return 0;
+out:
+	return new_ns;
+}
+
+int copy_namespace(int flags, struct task_struct *tsk)
+{
+	struct namespace *namespace = tsk->namespace;
+	struct namespace *new_ns;
+	int err = 0;
+
+	if (!namespace)
+		return 0;
+
+	get_namespace(namespace);
+
+	if (!(flags & CLONE_NEWNS))
+		return 0;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		err = -EPERM;
+		goto out;
+	}
+
+	new_ns = dup_namespace(tsk, tsk->fs);
+	if (!new_ns) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	tsk->namespace = new_ns;
 
 out:
 	put_namespace(namespace);
-	return -ENOMEM;
+	return err;
 }
 
 asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index e897e00..c0a754e 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -465,10 +465,11 @@
 					"number from server, using default\n");
 			port = nfsd_port;
 		}
-		nfs_port = htons(port);
+		nfs_port = port;
 		dprintk("Root-NFS: Portmapper on server returned %d "
 			"as nfsd port\n", port);
 	}
+	nfs_port = htons(nfs_port);
 
 	if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
 		printk(KERN_ERR "Root-NFS: Unable to get mountd port "
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index a00fe86..6d63f1d 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -195,10 +195,12 @@
 
 	/* Openowner is now set, so sequence id will get bumped.  Now we need
 	 * these checks before we do any creates: */
+	status = nfserr_grace;
 	if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
-		return nfserr_grace;
+		goto out;
+	status = nfserr_no_grace;
 	if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
-		return nfserr_no_grace;
+		goto out;
 
 	switch (open->op_claim_type) {
 		case NFS4_OPEN_CLAIM_DELEGATE_CUR:
diff --git a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c
index a3ec238..e664ac1 100644
--- a/fs/reiserfs/hashes.c
+++ b/fs/reiserfs/hashes.c
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/reiserfs_fs.h>
 #include <asm/types.h>
-#include <asm/bug.h>
 
 #define DELTA 0x9E3779B9
 #define FULLROUNDS 10		/* 32 is overkill, 16 is strong crypto */
diff --git a/fs/select.c b/fs/select.c
index c0f02d3..bc60a3e 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -510,9 +510,9 @@
 
 	if (sig) {
 		if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t))
-		    || __get_user(up, (sigset_t * __user *)sig)
+		    || __get_user(up, (sigset_t __user * __user *)sig)
 		    || __get_user(sigsetsize,
-				(size_t * __user)(sig+sizeof(void *))))
+				(size_t __user *)(sig+sizeof(void *))))
 			return -EFAULT;
 	}
 
diff --git a/fs/super.c b/fs/super.c
index c177b92..3029421 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -247,8 +247,9 @@
 
 		/* Forget any remaining inodes */
 		if (invalidate_inodes(sb)) {
-			printk("VFS: Busy inodes after unmount. "
-			   "Self-destruct in 5 seconds.  Have a nice day...\n");
+			printk("VFS: Busy inodes after unmount of %s. "
+			   "Self-destruct in 5 seconds.  Have a nice day...\n",
+			   sb->s_id);
 		}
 
 		unlock_kernel();
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 9892268..8f2beec 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -747,10 +747,11 @@
 			struct backing_dev_info *bdi;
 
 			bdi = inode->i_mapping->backing_dev_info;
+			wbc->nr_to_write--;
 			if (bdi_write_congested(bdi)) {
 				wbc->encountered_congestion = 1;
 				done = 1;
-			} else if (--wbc->nr_to_write <= 0) {
+			} else if (wbc->nr_to_write <= 0) {
 				done = 1;
 			}
 		}
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index eda7919..d7f6f2d 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -673,6 +673,8 @@
 	if (ia_valid & ATTR_ATIME) {
 		vattr.va_mask |= XFS_AT_ATIME;
 		vattr.va_atime = attr->ia_atime;
+		if (ia_valid & ATTR_ATIME_SET)
+			inode->i_atime = attr->ia_atime;
 	}
 	if (ia_valid & ATTR_MTIME) {
 		vattr.va_mask |= XFS_AT_MTIME;
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index cc9c7e8..f3b7b1a 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -572,7 +572,7 @@
    if something tries to do an invalid cmpxchg().  */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
-static inline unsigned long
+static __always_inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
 	switch (size) {
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index f5bcc9a..b726acf 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -116,7 +116,11 @@
 					->offset[((vaddr)&4095)>>2]
 #define __REG32(paddr)		__REGV32(io_p2v(paddr))
 
-extern void omap_map_common_io(void);
+extern void omap1_map_common_io(void);
+extern void omap1_init_common_hw(void);
+
+extern void omap2_map_common_io(void);
+extern void omap2_init_common_hw(void);
 
 #else
 
diff --git a/include/asm-arm/mutex.h b/include/asm-arm/mutex.h
index 6caa59f..cb29d84 100644
--- a/include/asm-arm/mutex.h
+++ b/include/asm-arm/mutex.h
@@ -23,72 +23,71 @@
  * simply bail out immediately through the slow path where the lock will be
  * reattempted until it succeeds.
  */
-#define __mutex_fastpath_lock(count, fail_fn)				\
-do {									\
-	int __ex_flag, __res;						\
-									\
-	typecheck(atomic_t *, count);					\
-	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
-									\
-	__asm__ (							\
-		"ldrex	%0, [%2]	\n"				\
-		"sub	%0, %0, #1	\n"				\
-		"strex	%1, %0, [%2]	\n"				\
-									\
-		: "=&r" (__res), "=&r" (__ex_flag)			\
-		: "r" (&(count)->counter)				\
-		: "cc","memory" );					\
-									\
-	if (unlikely(__res || __ex_flag))				\
-		fail_fn(count);						\
-} while (0)
+static inline void
+__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
+{
+	int __ex_flag, __res;
 
-#define __mutex_fastpath_lock_retval(count, fail_fn)			\
-({									\
-	int __ex_flag, __res;						\
-									\
-	typecheck(atomic_t *, count);					\
-	typecheck_fn(fastcall int (*)(atomic_t *), fail_fn);		\
-									\
-	__asm__ (							\
-		"ldrex	%0, [%2]	\n"				\
-		"sub	%0, %0, #1	\n"				\
-		"strex	%1, %0, [%2]	\n"				\
-									\
-		: "=&r" (__res), "=&r" (__ex_flag)			\
-		: "r" (&(count)->counter)				\
-		: "cc","memory" );					\
-									\
-	__res |= __ex_flag;						\
-	if (unlikely(__res != 0))					\
-		__res = fail_fn(count);					\
-	__res;								\
-})
+	__asm__ (
+
+		"ldrex	%0, [%2]	\n\t"
+		"sub	%0, %0, #1	\n\t"
+		"strex	%1, %0, [%2]	"
+
+		: "=&r" (__res), "=&r" (__ex_flag)
+		: "r" (&(count)->counter)
+		: "cc","memory" );
+
+	__res |= __ex_flag;
+	if (unlikely(__res != 0))
+		fail_fn(count);
+}
+
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
+{
+	int __ex_flag, __res;
+
+	__asm__ (
+
+		"ldrex	%0, [%2]	\n\t"
+		"sub	%0, %0, #1	\n\t"
+		"strex	%1, %0, [%2]	"
+
+		: "=&r" (__res), "=&r" (__ex_flag)
+		: "r" (&(count)->counter)
+		: "cc","memory" );
+
+	__res |= __ex_flag;
+	if (unlikely(__res != 0))
+		__res = fail_fn(count);
+	return __res;
+}
 
 /*
  * Same trick is used for the unlock fast path. However the original value,
  * rather than the result, is used to test for success in order to have
  * better generated assembly.
  */
-#define __mutex_fastpath_unlock(count, fail_fn)				\
-do {									\
-	int __ex_flag, __res, __orig;					\
-									\
-	typecheck(atomic_t *, count);					\
-	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
-									\
-	__asm__ (							\
-		"ldrex	%0, [%3]	\n"				\
-		"add	%1, %0, #1	\n"				\
-		"strex	%2, %1, [%3]	\n"				\
-									\
-		: "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)	\
-		: "r" (&(count)->counter)				\
-		: "cc","memory" );					\
-									\
-	if (unlikely(__orig || __ex_flag))				\
-		fail_fn(count);						\
-} while (0)
+static inline void
+__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
+{
+	int __ex_flag, __res, __orig;
+
+	__asm__ (
+
+		"ldrex	%0, [%3]	\n\t"
+		"add	%1, %0, #1	\n\t"
+		"strex	%2, %1, [%3]	"
+
+		: "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
+		: "r" (&(count)->counter)
+		: "cc","memory" );
+
+	__orig |= __ex_flag;
+	if (unlikely(__orig != 0))
+		fail_fn(count);
+}
 
 /*
  * If the unlock was done on a contended lock, or if the unlock simply fails
@@ -110,12 +109,12 @@
 
 	__asm__ (
 
-		"1: ldrex	%0, [%3]	\n"
-		"subs		%1, %0, #1	\n"
-		"strexeq	%2, %1, [%3]	\n"
-		"movlt		%0, #0		\n"
-		"cmpeq		%2, #0		\n"
-		"bgt		1b		\n"
+		"1: ldrex	%0, [%3]	\n\t"
+		"subs		%1, %0, #1	\n\t"
+		"strexeq	%2, %1, [%3]	\n\t"
+		"movlt		%0, #0		\n\t"
+		"cmpeq		%2, #0		\n\t"
+		"bgt		1b		"
 
 		: "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
 		: "r" (&count->counter)
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 36a92ed..399145a 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -507,7 +507,7 @@
 #define smp_rmb()	rmb()
 #define smp_wmb()	wmb()
 #define smp_read_barrier_depends()	read_barrier_depends()
-#define set_mb(var, value) do { xchg(&var, value); } while (0)
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 #else
 #define smp_mb()	barrier()
 #define smp_rmb()	barrier()
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 597496e..cf6f2cd 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -315,8 +315,9 @@
 #define __NR_faccessat		307
 #define __NR_pselect6		308
 #define __NR_ppoll		309
+#define __NR_unshare		310
 
-#define NR_syscalls 310
+#define NR_syscalls 311
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 09b9902..23c8e1b 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -559,6 +559,23 @@
 
 #define cpu_relax()	ia64_hint(ia64_hint_pause)
 
+static inline int
+ia64_get_irr(unsigned int vector)
+{
+	unsigned int reg = vector / 64;
+	unsigned int bit = vector % 64;
+	u64 irr;
+
+	switch (reg) {
+	case 0: irr = ia64_getreg(_IA64_REG_CR_IRR0); break;
+	case 1: irr = ia64_getreg(_IA64_REG_CR_IRR1); break;
+	case 2: irr = ia64_getreg(_IA64_REG_CR_IRR2); break;
+	case 3: irr = ia64_getreg(_IA64_REG_CR_IRR3); break;
+	}
+
+	return test_bit(bit, &irr);
+}
+
 static inline void
 ia64_set_lrr0 (unsigned long val)
 {
diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
index 313cad0..0b210ab 100644
--- a/include/asm-ia64/sal.h
+++ b/include/asm-ia64/sal.h
@@ -658,15 +658,7 @@
 	return isrv.status;
 }
 
-/* Flush all the processor and platform level instruction and/or data caches */
-static inline s64
-ia64_sal_cache_flush (u64 cache_type)
-{
-	struct ia64_sal_retval isrv;
-	SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
-	return isrv.status;
-}
-
+extern s64 ia64_sal_cache_flush (u64 cache_type);
 
 /* Initialize all the processor and platform level instruction and data caches */
 static inline s64
diff --git a/include/asm-ia64/sn/bte.h b/include/asm-ia64/sn/bte.h
index f50da3d..01e5b41 100644
--- a/include/asm-ia64/sn/bte.h
+++ b/include/asm-ia64/sn/bte.h
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
@@ -100,13 +100,28 @@
 #define BTE_LNSTAT_STORE(_bte, _x)					\
 			HUB_S(_bte->bte_base_addr, (_x))
 #define BTE_SRC_STORE(_bte, _x)						\
-			HUB_S(_bte->bte_source_addr, (_x))
+({									\
+		u64 __addr = ((_x) & ~AS_MASK);				\
+		if (is_shub2()) 					\
+			__addr = SH2_TIO_PHYS_TO_DMA(__addr);		\
+		HUB_S(_bte->bte_source_addr, __addr);			\
+})
 #define BTE_DEST_STORE(_bte, _x)					\
-			HUB_S(_bte->bte_destination_addr, (_x))
+({									\
+		u64 __addr = ((_x) & ~AS_MASK);				\
+		if (is_shub2()) 					\
+			__addr = SH2_TIO_PHYS_TO_DMA(__addr);		\
+		HUB_S(_bte->bte_destination_addr, __addr);		\
+})
 #define BTE_CTRL_STORE(_bte, _x)					\
 			HUB_S(_bte->bte_control_addr, (_x))
 #define BTE_NOTIF_STORE(_bte, _x)					\
-			HUB_S(_bte->bte_notify_addr, (_x))
+({									\
+		u64 __addr = ia64_tpa((_x) & ~AS_MASK);			\
+		if (is_shub2()) 					\
+			__addr = SH2_TIO_PHYS_TO_DMA(__addr);		\
+		HUB_S(_bte->bte_notify_addr, __addr);			\
+})
 
 #define BTE_START_TRANSFER(_bte, _len, _mode)				\
 	is_shub2() ? BTE_CTRL_STORE(_bte, IBLS_BUSY | (_mode << 24) | _len) \
diff --git a/include/asm-ia64/sn/intr.h b/include/asm-ia64/sn/intr.h
index a343137..60a51a4 100644
--- a/include/asm-ia64/sn/intr.h
+++ b/include/asm-ia64/sn/intr.h
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_INTR_H
@@ -11,26 +11,26 @@
 
 #include <linux/rcupdate.h>
 
-#define SGI_UART_VECTOR		(0xe9)
+#define SGI_UART_VECTOR		0xe9
 
 /* Reserved IRQs : Note, not to exceed IA64_SN2_FIRST_DEVICE_VECTOR */
-#define SGI_XPC_ACTIVATE                (0x30)
-#define SGI_II_ERROR                    (0x31)
-#define SGI_XBOW_ERROR                  (0x32)
-#define SGI_PCIASIC_ERROR               (0x33)
-#define SGI_ACPI_SCI_INT                (0x34)
-#define SGI_TIOCA_ERROR                 (0x35)
-#define SGI_TIO_ERROR                   (0x36)
-#define SGI_TIOCX_ERROR                 (0x37)
-#define SGI_MMTIMER_VECTOR              (0x38)
-#define SGI_XPC_NOTIFY                  (0xe7)
+#define SGI_XPC_ACTIVATE	0x30
+#define SGI_II_ERROR		0x31
+#define SGI_XBOW_ERROR		0x32
+#define SGI_PCIASIC_ERROR	0x33
+#define SGI_ACPI_SCI_INT	0x34
+#define SGI_TIOCA_ERROR		0x35
+#define SGI_TIO_ERROR		0x36
+#define SGI_TIOCX_ERROR		0x37
+#define SGI_MMTIMER_VECTOR	0x38
+#define SGI_XPC_NOTIFY		0xe7
 
-#define IA64_SN2_FIRST_DEVICE_VECTOR    (0x3c)
-#define IA64_SN2_LAST_DEVICE_VECTOR     (0xe6)
+#define IA64_SN2_FIRST_DEVICE_VECTOR	0x3c
+#define IA64_SN2_LAST_DEVICE_VECTOR	0xe6
 
-#define SN2_IRQ_RESERVED        (0x1)
-#define SN2_IRQ_CONNECTED       (0x2)
-#define SN2_IRQ_SHARED          (0x4)
+#define SN2_IRQ_RESERVED	0x1
+#define SN2_IRQ_CONNECTED	0x2
+#define SN2_IRQ_SHARED		0x4
 
 // The SN PROM irq struct
 struct sn_irq_info {
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 80c5a23..0625387 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -249,32 +249,7 @@
 # define switch_to(prev,next,last)	__switch_to(prev, next, last)
 #endif
 
-/*
- * On IA-64, we don't want to hold the runqueue's lock during the low-level context-switch,
- * because that could cause a deadlock.  Here is an example by Erich Focht:
- *
- * Example:
- * CPU#0:
- * schedule()
- *    -> spin_lock_irq(&rq->lock)
- *    -> context_switch()
- *       -> wrap_mmu_context()
- *          -> read_lock(&tasklist_lock)
- *
- * CPU#1:
- * sys_wait4() or release_task() or forget_original_parent()
- *    -> write_lock(&tasklist_lock)
- *    -> do_notify_parent()
- *       -> wake_up_parent()
- *          -> try_to_wake_up()
- *             -> spin_lock_irq(&parent_rq->lock)
- *
- * If the parent's rq happens to be on CPU#0, we'll wait for the rq->lock
- * of that CPU which will not be released, because there we wait for the
- * tasklist_lock to become available.
- */
 #define __ARCH_WANT_UNLOCKED_CTXSW
-
 #define ARCH_HAS_PREFETCH_SWITCH_STACK
 #define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
 
diff --git a/include/asm-m68knommu/hardirq.h b/include/asm-m68knommu/hardirq.h
index e8659e7..476180f 100644
--- a/include/asm-m68knommu/hardirq.h
+++ b/include/asm-m68knommu/hardirq.h
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <linux/cache.h>
 #include <linux/threads.h>
+#include <asm/irq.h>
 
 typedef struct {
 	unsigned int __softirq_pending;
diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h
index 2e7e651..1ce0518 100644
--- a/include/asm-mips/abi.h
+++ b/include/asm-mips/abi.h
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2005 by Ralf Baechle
+ * Copyright (C) 2005, 06 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2005 MIPS Technologies, Inc.
  */
 #ifndef _ASM_ABI_H
@@ -13,7 +13,7 @@
 #include <asm/siginfo.h>
 
 struct mips_abi {
-	int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs);
+	void (* const do_signal)(struct pt_regs *regs);
 	int (* const setup_frame)(struct k_sigaction * ka,
 	                          struct pt_regs *regs, int signr,
 	                          sigset_t *set);
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 3b0c8aa..8e80205 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -644,44 +644,6 @@
 }
 
 /*
- * flz - find last zero in word.
- * @word: The word to search
- *
- * Returns 0..SZLONG-1
- * Undefined if no zero exists, so code should check against ~0UL first.
- */
-static inline unsigned long flz(unsigned long word)
-{
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-	return __ilog2(~word);
-#else
-#ifdef CONFIG_32BIT
-	int r = 31, s;
-	word = ~word;
-	s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s;
-	s = 8;  if ((word & 0xff000000)) s = 0; r -= s; word <<= s;
-	s = 4;  if ((word & 0xf0000000)) s = 0; r -= s; word <<= s;
-	s = 2;  if ((word & 0xc0000000)) s = 0; r -= s; word <<= s;
-	s = 1;  if ((word & 0x80000000)) s = 0; r -= s;
-
-	return r;
-#endif
-#ifdef CONFIG_64BIT
-	int r = 63, s;
-	word = ~word;
-	s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s;
-	s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s;
-	s = 8;  if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s;
-	s = 4;  if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s;
-	s = 2;  if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s;
-	s = 1;  if ((word & 0x8000000000000000UL)) s = 0; r -= s;
-
-	return r;
-#endif
-#endif
-}
-
-/*
  * fls - find last bit set.
  * @word: The word to search
  *
@@ -690,11 +652,55 @@
  */
 static inline unsigned long fls(unsigned long word)
 {
+#ifdef CONFIG_32BIT
+#ifdef CONFIG_CPU_MIPS32
+	__asm__ ("clz %0, %1" : "=r" (word) : "r" (word));
+
+	return 32 - word;
+#else
+	{
+	int r = 32, s;
+
 	if (word == 0)
 		return 0;
 
-	return flz(~word) + 1;
+	s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s;
+	s = 8;  if ((word & 0xff000000)) s = 0; r -= s; word <<= s;
+	s = 4;  if ((word & 0xf0000000)) s = 0; r -= s; word <<= s;
+	s = 2;  if ((word & 0xc0000000)) s = 0; r -= s; word <<= s;
+	s = 1;  if ((word & 0x80000000)) s = 0; r -= s;
+
+	return r;
+	}
+#endif
+#endif /* CONFIG_32BIT */
+
+#ifdef CONFIG_64BIT
+#ifdef CONFIG_CPU_MIPS64
+
+	__asm__ ("dclz %0, %1" : "=r" (word) : "r" (word));
+
+	return 64 - word;
+#else
+	{
+	int r = 64, s;
+
+	if (word == 0)
+		return 0;
+
+	s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s;
+	s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s;
+	s = 8;  if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s;
+	s = 4;  if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s;
+	s = 2;  if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s;
+	s = 1;  if ((word & 0x8000000000000000UL)) s = 0; r -= s;
+
+	return r;
+	}
+#endif
+#endif /* CONFIG_64BIT */
 }
+
 #define fls64(x)   generic_fls64(x)
 
 /*
diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h
index d1fe9e5..584f812 100644
--- a/include/asm-mips/byteorder.h
+++ b/include/asm-mips/byteorder.h
@@ -8,10 +8,39 @@
 #ifndef _ASM_BYTEORDER_H
 #define _ASM_BYTEORDER_H
 
+#include <linux/config.h>
+#include <linux/compiler.h>
 #include <asm/types.h>
 
 #ifdef __GNUC__
 
+#ifdef CONFIG_CPU_MIPSR2
+
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+{
+	__asm__(
+	"	wsbh	%0, %1			\n"
+	: "=r" (x)
+	: "r" (x));
+
+	return x;
+}
+#define __arch__swab16(x)	___arch__swab16(x)
+
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+{
+	__asm__(
+	"	wsbh	%0, %1			\n"
+	"	rotr	%0, %0, 16		\n"
+	: "=r" (x)
+	: "r" (x));
+
+	return x;
+}
+#define __arch__swab32(x)	___arch__swab32(x)
+
+#endif /* CONFIG_CPU_MIPSR2 */
+
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 #  define __BYTEORDER_HAS_U64__
 #  define __SWAB_64_THRU_32__
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index a18ba2e..aeae9fa 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -49,8 +49,7 @@
 
 extern void (*flush_icache_page)(struct vm_area_struct *vma,
 	struct page *page);
-extern void (*flush_icache_range)(unsigned long __user start,
-	unsigned long __user end);
+extern void (*flush_icache_range)(unsigned long start, unsigned long end);
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
 
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
index 2fc9063..6111a0c 100644
--- a/include/asm-mips/hazards.h
+++ b/include/asm-mips/hazards.h
@@ -100,7 +100,7 @@
 
 __asm__(
 	"	.macro	_ssnop					\n\t"
-	"	sll	$0, $2, 1				\n\t"
+	"	sll	$0, $0, 1				\n\t"
 	"	.endm						\n\t"
 	"							\n\t"
 	"	.macro	_ehb					\n\t"
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h
index abdf54e..7743487 100644
--- a/include/asm-mips/interrupt.h
+++ b/include/asm-mips/interrupt.h
@@ -47,6 +47,17 @@
  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
  * no nops at all.
  */
+/*
+ * For TX49, operating only IE bit is not enough.
+ *
+ * If mfc0 $12 follows store and the mfc0 is last instruction of a
+ * page and fetching the next instruction causes TLB miss, the result
+ * of the mfc0 might wrongly contain EXL bit.
+ *
+ * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
+ *
+ * Workaround: mask EXL bit of the result or place a nop before mfc0.
+ */
 __asm__ (
 	"	.macro	local_irq_disable\n"
 	"	.set	push						\n"
@@ -55,8 +66,8 @@
 	"	di							\n"
 #else
 	"	mfc0	$1,$12						\n"
-	"	ori	$1,1						\n"
-	"	xori	$1,1						\n"
+	"	ori	$1,0x1f						\n"
+	"	xori	$1,0x1f						\n"
 	"	.set	noreorder					\n"
 	"	mtc0	$1,$12						\n"
 #endif
@@ -96,8 +107,8 @@
 	"	andi	\\result, 1					\n"
 #else
 	"	mfc0	\\result, $12					\n"
-	"	ori	$1, \\result, 1					\n"
-	"	xori	$1, 1						\n"
+	"	ori	$1, \\result, 0x1f				\n"
+	"	xori	$1, 0x1f					\n"
 	"	.set	noreorder					\n"
 	"	mtc0	$1, $12						\n"
 #endif
@@ -114,6 +125,7 @@
 
 __asm__ (
 	"	.macro	local_irq_restore flags				\n"
+	"	.set	push						\n"
 	"	.set	noreorder					\n"
 	"	.set	noat						\n"
 #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
@@ -135,14 +147,13 @@
 #else
 	"	mfc0	$1, $12						\n"
 	"	andi	\\flags, 1					\n"
-	"	ori	$1, 1						\n"
-	"	xori	$1, 1						\n"
+	"	ori	$1, 0x1f					\n"
+	"	xori	$1, 0x1f					\n"
 	"	or	\\flags, $1					\n"
 	"	mtc0	\\flags, $12					\n"
 #endif
 	"	irq_disable_hazard					\n"
-	"	.set	at						\n"
-	"	.set	reorder						\n"
+	"	.set	pop						\n"
 	"	.endm							\n");
 
 #define local_irq_restore(flags)					\
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index d426857..5a4c8a5 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
-#include <asm/bug.h>
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
@@ -57,38 +56,38 @@
  * variations of functions: non-prefixed ones that preserve the value
  * and prefixed ones that preserve byte addresses.  The latters are
  * typically used for moving raw data between a peripheral and memory (cf.
- * string I/O functions), hence the "mem_" prefix.
+ * string I/O functions), hence the "__mem_" prefix.
  */
 #if defined(CONFIG_SWAP_IO_SPACE)
 
 # define ioswabb(x)		(x)
-# define mem_ioswabb(x)		(x)
+# define __mem_ioswabb(x)	(x)
 # ifdef CONFIG_SGI_IP22
 /*
  * IP22 seems braindead enough to swap 16bits values in hardware, but
  * not 32bits.  Go figure... Can't tell without documentation.
  */
 #  define ioswabw(x)		(x)
-#  define mem_ioswabw(x)	le16_to_cpu(x)
+#  define __mem_ioswabw(x)	le16_to_cpu(x)
 # else
 #  define ioswabw(x)		le16_to_cpu(x)
-#  define mem_ioswabw(x)	(x)
+#  define __mem_ioswabw(x)	(x)
 # endif
 # define ioswabl(x)		le32_to_cpu(x)
-# define mem_ioswabl(x)		(x)
+# define __mem_ioswabl(x)	(x)
 # define ioswabq(x)		le64_to_cpu(x)
-# define mem_ioswabq(x)		(x)
+# define __mem_ioswabq(x)	(x)
 
 #else
 
 # define ioswabb(x)		(x)
-# define mem_ioswabb(x)		(x)
+# define __mem_ioswabb(x)	(x)
 # define ioswabw(x)		(x)
-# define mem_ioswabw(x)		cpu_to_le16(x)
+# define __mem_ioswabw(x)	cpu_to_le16(x)
 # define ioswabl(x)		(x)
-# define mem_ioswabl(x)		cpu_to_le32(x)
+# define __mem_ioswabl(x)	cpu_to_le32(x)
 # define ioswabq(x)		(x)
-# define mem_ioswabq(x)		cpu_to_le32(x)
+# define __mem_ioswabq(x)	cpu_to_le32(x)
 
 #endif
 
@@ -343,7 +342,7 @@
 		BUG();							\
 }									\
 									\
-static inline type pfx##read##bwlq(volatile void __iomem *mem)		\
+static inline type pfx##read##bwlq(const volatile void __iomem *mem)	\
 {									\
 	volatile type *__mem;						\
 	type __val;							\
@@ -418,7 +417,7 @@
 									\
 __BUILD_MEMORY_PFX(__raw_, bwlq, type)					\
 __BUILD_MEMORY_PFX(, bwlq, type)					\
-__BUILD_MEMORY_PFX(mem_, bwlq, type)					\
+__BUILD_MEMORY_PFX(__mem_, bwlq, type)					\
 
 BUILDIO_MEM(b, u8)
 BUILDIO_MEM(w, u16)
@@ -431,7 +430,7 @@
 
 #define BUILDIO_IOPORT(bwlq, type)					\
 	__BUILD_IOPORT_PFX(, bwlq, type)				\
-	__BUILD_IOPORT_PFX(mem_, bwlq, type)
+	__BUILD_IOPORT_PFX(__mem_, bwlq, type)
 
 BUILDIO_IOPORT(b, u8)
 BUILDIO_IOPORT(w, u16)
@@ -465,7 +464,7 @@
 	const volatile type *__addr = addr;				\
 									\
 	while (count--) {						\
-		mem_write##bwlq(*__addr, mem);				\
+		__mem_write##bwlq(*__addr, mem);			\
 		__addr++;						\
 	}								\
 }									\
@@ -476,7 +475,7 @@
 	volatile type *__addr = addr;					\
 									\
 	while (count--) {						\
-		*__addr = mem_read##bwlq(mem);				\
+		*__addr = __mem_read##bwlq(mem);			\
 		__addr++;						\
 	}								\
 }
@@ -489,7 +488,7 @@
 	const volatile type *__addr = addr;				\
 									\
 	while (count--) {						\
-		mem_out##bwlq(*__addr, port);				\
+		__mem_out##bwlq(*__addr, port);				\
 		__addr++;						\
 	}								\
 }									\
@@ -500,7 +499,7 @@
 	volatile type *__addr = addr;					\
 									\
 	while (count--) {						\
-		*__addr = mem_in##bwlq(port);				\
+		*__addr = __mem_in##bwlq(port);				\
 		__addr++;						\
 	}								\
 }
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
index 8e1d7ed..4686e17 100644
--- a/include/asm-mips/mach-au1x00/au1000.h
+++ b/include/asm-mips/mach-au1x00/au1000.h
@@ -1198,7 +1198,11 @@
 
 /* UARTS 0-3 */
 #define UART_BASE                 UART0_ADDR
+#ifdef	CONFIG_SOC_AU1200
+#define UART_DEBUG_BASE           UART1_ADDR
+#else
 #define UART_DEBUG_BASE           UART3_ADDR
+#endif
 
 #define UART_RX		0	/* Receive buffer */
 #define UART_TX		4	/* Transmit buffer */
diff --git a/include/asm-mips/cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h
similarity index 100%
rename from include/asm-mips/cobalt/cobalt.h
rename to include/asm-mips/mach-cobalt/cobalt.h
diff --git a/include/asm-mips/mach-cobalt/cpu-feature-overrides.h b/include/asm-mips/mach-cobalt/cpu-feature-overrides.h
new file mode 100644
index 0000000..ace8c5e
--- /dev/null
+++ b/include/asm-mips/mach-cobalt/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
+#define __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/config.h>
+
+#define cpu_has_tlb		1
+#define cpu_has_4kex		1
+#define cpu_has_3k_cache	0
+#define cpu_has_4k_cache	1
+#define cpu_has_tx39_cache	0
+#define cpu_has_sb1_cache	0
+#define cpu_has_fpu		1
+#define cpu_has_32fpr		1
+#define cpu_has_counter		1
+#define cpu_has_watch		0
+#define cpu_has_divec		1
+#define cpu_has_vce		0
+#define cpu_has_cache_cdex_p	0
+#define cpu_has_cache_cdex_s	0
+#define cpu_has_prefetch	0
+#define cpu_has_mcheck		0
+#define cpu_has_ejtag		0
+
+#define cpu_has_subset_pcaches	0
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+#define cpu_scache_line_size()	0
+
+#ifdef CONFIG_64BIT
+#define cpu_has_llsc            0
+#else
+#define cpu_has_llsc            1
+#endif
+
+#define cpu_has_mips16		0
+#define cpu_has_mdmx		0
+#define cpu_has_mips3d		0
+#define cpu_has_smartmips	0
+#define cpu_has_vtag_icache	0
+#define cpu_has_ic_fills_f_dc	0
+#define cpu_icache_snoops_remote_store	0
+#define cpu_has_dsp		0
+
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
+#endif /* __ASM_COBALT_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/cobalt/mach-gt64120.h b/include/asm-mips/mach-cobalt/mach-gt64120.h
similarity index 100%
rename from include/asm-mips/cobalt/mach-gt64120.h
rename to include/asm-mips/mach-cobalt/mach-gt64120.h
diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
index b80c307..36070b5 100644
--- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
@@ -18,7 +18,7 @@
  * so, for 64bit IP32 kernel we just don't use ll/sc.
  * This does not affect luserland.
  */
-#if defined(CONFIG_CPU_R5000) && defined(CONFIG_64BIT)
+#if (defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)) && defined(CONFIG_64BIT)
 #define cpu_has_llsc		0
 #else
 #define cpu_has_llsc		1
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index a5ea9d8..cc53196 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -166,123 +166,6 @@
 		: "r" (base),						\
 		  "i" (op));
 
-static inline void blast_dcache16(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.dcache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-	unsigned long ws_end = current_cpu_data.dcache.ways <<
-	                       current_cpu_data.dcache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x200)
-			cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_dcache16_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-
-	do {
-		cache16_unroll32(start,Hit_Writeback_Inv_D);
-		start += 0x200;
-	} while (start < end);
-}
-
-static inline void blast_dcache16_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-	unsigned long ws_end = current_cpu_data.dcache.ways <<
-	                       current_cpu_data.dcache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x200)
-			cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_icache16(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.icache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x200)
-			cache16_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_icache16_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-
-	do {
-		cache16_unroll32(start,Hit_Invalidate_I);
-		start += 0x200;
-	} while (start < end);
-}
-
-static inline void blast_icache16_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x200)
-			cache16_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_scache16(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.scache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x200)
-			cache16_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
-static inline void blast_scache16_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = page + PAGE_SIZE;
-
-	do {
-		cache16_unroll32(start,Hit_Writeback_Inv_SD);
-		start += 0x200;
-	} while (start < end);
-}
-
-static inline void blast_scache16_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x200)
-			cache16_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
 #define cache32_unroll32(base,op)					\
 	__asm__ __volatile__(						\
 	"	.set push					\n"	\
@@ -309,123 +192,6 @@
 		: "r" (base),						\
 		  "i" (op));
 
-static inline void blast_dcache32(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.dcache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-	unsigned long ws_end = current_cpu_data.dcache.ways <<
-	                       current_cpu_data.dcache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x400)
-			cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_dcache32_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-
-	do {
-		cache32_unroll32(start,Hit_Writeback_Inv_D);
-		start += 0x400;
-	} while (start < end);
-}
-
-static inline void blast_dcache32_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
-	unsigned long ws_end = current_cpu_data.dcache.ways <<
-	                       current_cpu_data.dcache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x400)
-			cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
-}
-
-static inline void blast_icache32(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.icache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x400)
-			cache32_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_icache32_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-
-	do {
-		cache32_unroll32(start,Hit_Invalidate_I);
-		start += 0x400;
-	} while (start < end);
-}
-
-static inline void blast_icache32_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x400)
-			cache32_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_scache32(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.scache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x400)
-			cache32_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
-static inline void blast_scache32_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = page + PAGE_SIZE;
-
-	do {
-		cache32_unroll32(start,Hit_Writeback_Inv_SD);
-		start += 0x400;
-	} while (start < end);
-}
-
-static inline void blast_scache32_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x400)
-			cache32_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
 #define cache64_unroll32(base,op)					\
 	__asm__ __volatile__(						\
 	"	.set push					\n"	\
@@ -452,84 +218,6 @@
 		: "r" (base),						\
 		  "i" (op));
 
-static inline void blast_icache64(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.icache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x800)
-			cache64_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_icache64_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-
-	do {
-		cache64_unroll32(start,Hit_Invalidate_I);
-		start += 0x800;
-	} while (start < end);
-}
-
-static inline void blast_icache64_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
-	unsigned long ws_end = current_cpu_data.icache.ways <<
-	                       current_cpu_data.icache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x800)
-			cache64_unroll32(addr|ws,Index_Invalidate_I);
-}
-
-static inline void blast_scache64(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.scache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x800)
-			cache64_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
-static inline void blast_scache64_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = page + PAGE_SIZE;
-
-	do {
-		cache64_unroll32(start,Hit_Writeback_Inv_SD);
-		start += 0x800;
-	} while (start < end);
-}
-
-static inline void blast_scache64_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x800)
-			cache64_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
-
 #define cache128_unroll32(base,op)					\
 	__asm__ __volatile__(						\
 	"	.set push					\n"	\
@@ -556,43 +244,55 @@
 		: "r" (base),						\
 		  "i" (op));
 
-static inline void blast_scache128(void)
-{
-	unsigned long start = INDEX_BASE;
-	unsigned long end = start + current_cpu_data.scache.waysize;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x1000)
-			cache128_unroll32(addr|ws,Index_Writeback_Inv_SD);
+/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
+#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \
+static inline void blast_##pfx##cache##lsize(void)			\
+{									\
+	unsigned long start = INDEX_BASE;				\
+	unsigned long end = start + current_cpu_data.desc.waysize;	\
+	unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;	\
+	unsigned long ws_end = current_cpu_data.desc.ways <<		\
+	                       current_cpu_data.desc.waybit;		\
+	unsigned long ws, addr;						\
+									\
+	for (ws = 0; ws < ws_end; ws += ws_inc)				\
+		for (addr = start; addr < end; addr += lsize * 32)	\
+			cache##lsize##_unroll32(addr|ws,indexop);	\
+}									\
+									\
+static inline void blast_##pfx##cache##lsize##_page(unsigned long page)	\
+{									\
+	unsigned long start = page;					\
+	unsigned long end = page + PAGE_SIZE;				\
+									\
+	do {								\
+		cache##lsize##_unroll32(start,hitop);			\
+		start += lsize * 32;					\
+	} while (start < end);						\
+}									\
+									\
+static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
+{									\
+	unsigned long start = page;					\
+	unsigned long end = start + PAGE_SIZE;				\
+	unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;	\
+	unsigned long ws_end = current_cpu_data.desc.ways <<		\
+	                       current_cpu_data.desc.waybit;		\
+	unsigned long ws, addr;						\
+									\
+	for (ws = 0; ws < ws_end; ws += ws_inc)				\
+		for (addr = start; addr < end; addr += lsize * 32)	\
+			cache##lsize##_unroll32(addr|ws,indexop);	\
 }
 
-static inline void blast_scache128_page(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = page + PAGE_SIZE;
-
-	do {
-		cache128_unroll32(start,Hit_Writeback_Inv_SD);
-		start += 0x1000;
-	} while (start < end);
-}
-
-static inline void blast_scache128_page_indexed(unsigned long page)
-{
-	unsigned long start = page;
-	unsigned long end = start + PAGE_SIZE;
-	unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit;
-	unsigned long ws_end = current_cpu_data.scache.ways <<
-	                       current_cpu_data.scache.waybit;
-	unsigned long ws, addr;
-
-	for (ws = 0; ws < ws_end; ws += ws_inc)
-		for (addr = start; addr < end; addr += 0x1000)
-			cache128_unroll32(addr|ws,Index_Writeback_Inv_SD);
-}
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
 
 #endif /* _ASM_R4KCACHE_H */
diff --git a/include/asm-mips/reboot.h b/include/asm-mips/reboot.h
index 2f10ebc..e48c0bf 100644
--- a/include/asm-mips/reboot.h
+++ b/include/asm-mips/reboot.h
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1999, 2001 by Ralf Baechle
+ * Copyright (C) 1997, 1999, 2001, 06 by Ralf Baechle
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #ifndef _ASM_REBOOT_H
@@ -11,6 +11,5 @@
 
 extern void (*_machine_restart)(char *command);
 extern void (*_machine_halt)(void);
-extern void (*_machine_power_off)(void);
 
 #endif /* _ASM_REBOOT_H */
diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h
index 5a06f6d..907da60 100644
--- a/include/asm-mips/string.h
+++ b/include/asm-mips/string.h
@@ -141,26 +141,4 @@
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
 
-#ifdef CONFIG_32BIT
-#define __HAVE_ARCH_MEMSCAN
-static __inline__ void *memscan(void *__addr, int __c, size_t __size)
-{
-	char *__end = (char *)__addr + __size;
-	unsigned char __uc = (unsigned char) __c;
-
-	__asm__(".set\tpush\n\t"
-		".set\tnoat\n\t"
-		".set\treorder\n\t"
-		"1:\tbeq\t%0,%1,2f\n\t"
-		"addiu\t%0,1\n\t"
-		"lbu\t$1,-1(%0)\n\t"
-		"bne\t$1,%z4,1b\n"
-		"2:\t.set\tpop"
-		: "=r" (__addr), "=r" (__end)
-		: "0" (__addr), "1" (__end), "Jr" (__uc));
-
-	return __addr;
-}
-#endif /* CONFIG_32BIT */
-
 #endif /* _ASM_STRING_H */
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index 1612b3f..fa193f8 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -114,6 +114,7 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_SYSCALL_AUDIT	4	/* syscall auditing active */
 #define TIF_SECCOMP		5	/* secure computing */
+#define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18
@@ -125,6 +126,7 @@
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
diff --git a/include/asm-mips/tx4927/tx4927.h b/include/asm-mips/tx4927/tx4927.h
index 3bb7f00..de85bd2 100644
--- a/include/asm-mips/tx4927/tx4927.h
+++ b/include/asm-mips/tx4927/tx4927.h
@@ -2,7 +2,7 @@
  * Author: MontaVista Software, Inc.
  *         source@mvista.com
  *
- * Copyright 2001-2002 MontaVista Software Inc.
+ * Copyright 2001-2006 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
@@ -30,10 +30,10 @@
 #include <asm/tx4927/tx4927_mips.h>
 
 /*
- This register naming came from the intergrate cpu/controoler name TX4927
+ This register naming came from the integrated CPU/controller name TX4927
  followed by the device name from table 4.2.2 on page 4-3 and then followed
  by the register name from table 4.2.3 on pages 4-4 to 4-8.  The manaul
- used is "TMPR4927BT Preliminary Rev 0.1 20.Jul.2001".
+ used was "TMPR4927BT Preliminary Rev 0.1 20.Jul.2001".
  */
 
 #define TX4927_SIO_0_BASE
@@ -251,8 +251,8 @@
 
 /* TX4927 Timer 0 (32-bit registers) */
 #define TX4927_TMR0_BASE                0xf000
-#define TX4927_TMR0_TMTCR0              0xf004
-#define TX4927_TMR0_TMTISR0             0xf008
+#define TX4927_TMR0_TMTCR0              0xf000
+#define TX4927_TMR0_TMTISR0             0xf004
 #define TX4927_TMR0_TMCPRA0             0xf008
 #define TX4927_TMR0_TMCPRB0             0xf00c
 #define TX4927_TMR0_TMITMR0             0xf010
@@ -264,8 +264,8 @@
 
 /* TX4927 Timer 1 (32-bit registers) */
 #define TX4927_TMR1_BASE                0xf100
-#define TX4927_TMR1_TMTCR1              0xf104
-#define TX4927_TMR1_TMTISR1             0xf108
+#define TX4927_TMR1_TMTCR1              0xf100
+#define TX4927_TMR1_TMTISR1             0xf104
 #define TX4927_TMR1_TMCPRA1             0xf108
 #define TX4927_TMR1_TMCPRB1             0xf10c
 #define TX4927_TMR1_TMITMR1             0xf110
@@ -277,13 +277,12 @@
 
 /* TX4927 Timer 2 (32-bit registers) */
 #define TX4927_TMR2_BASE                0xf200
-#define TX4927_TMR2_TMTCR2              0xf104
-#define TX4927_TMR2_TMTISR2             0xf208
+#define TX4927_TMR2_TMTCR2              0xf200
+#define TX4927_TMR2_TMTISR2             0xf204
 #define TX4927_TMR2_TMCPRA2             0xf208
-#define TX4927_TMR2_TMCPRB2             0xf20c
 #define TX4927_TMR2_TMITMR2             0xf210
 #define TX4927_TMR2_TMCCDR2             0xf220
-#define TX4927_TMR2_TMPGMR2             0xf230
+#define TX4927_TMR2_TMWTMR2             0xf240
 #define TX4927_TMR2_TMTRR2              0xf2f0
 #define TX4927_TMR2_LIMIT               0xf2ff
 
diff --git a/include/asm-mips/tx4927/tx4927_pci.h b/include/asm-mips/tx4927/tx4927_pci.h
index 165f6b8..66c0646 100644
--- a/include/asm-mips/tx4927/tx4927_pci.h
+++ b/include/asm-mips/tx4927/tx4927_pci.h
@@ -253,6 +253,16 @@
 #define TX4927_CCFG_PCIDIVMODE_5        0x00001000
 #define TX4927_CCFG_PCIDIVMODE_6        0x00001800
 
+#define TX4937_CCFG_PCIDIVMODE_MASK	0x00001c00
+#define TX4937_CCFG_PCIDIVMODE_8	0x00000000
+#define TX4937_CCFG_PCIDIVMODE_4	0x00000400
+#define TX4937_CCFG_PCIDIVMODE_9 	0x00000800
+#define TX4937_CCFG_PCIDIVMODE_4_5	0x00000c00
+#define TX4937_CCFG_PCIDIVMODE_10	0x00001000
+#define TX4937_CCFG_PCIDIVMODE_5	0x00001400
+#define TX4937_CCFG_PCIDIVMODE_11	0x00001800
+#define TX4937_CCFG_PCIDIVMODE_5_5	0x00001c00
+
 /* PCFG : Pin Configuration */
 #define TX4927_PCFG_PCICLKEN_ALL        0x003f0000
 #define TX4927_PCFG_PCICLKEN(ch)        (0x00010000<<(ch))
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index 41bb96b..91d813a 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -202,49 +202,49 @@
  * Yuck.  We need two variants, one for 64bit operation and one
  * for 32 bit mode and old iron.
  */
-#ifdef __mips64
-#define __GET_USER_DW(ptr) __get_user_asm("ld", ptr)
-#else
-#define __GET_USER_DW(ptr) __get_user_asm_ll32(ptr)
+#ifdef CONFIG_32BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm_ll32(val, ptr)
 #endif
+#ifdef CONFIG_64BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm(val, "ld", ptr)
+#endif
+
+extern void __get_user_unknown(void);
+
+#define __get_user_common(val, size, ptr)				\
+do {									\
+	switch (size) {							\
+	case 1: __get_user_asm(val, "lb", ptr); break;			\
+	case 2: __get_user_asm(val, "lh", ptr); break;			\
+	case 4: __get_user_asm(val, "lw", ptr); break;			\
+	case 8: __GET_USER_DW(val, ptr); break;				\
+	default: __get_user_unknown(); break;				\
+	}								\
+} while (0)
 
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
-	__typeof(*(ptr)) __gu_val =  (__typeof(*(ptr))) 0;		\
-	long __gu_err = 0;						\
+	long __gu_err;							\
 									\
-	switch (size) {							\
-	case 1: __get_user_asm("lb", ptr); break;			\
-	case 2: __get_user_asm("lh", ptr); break;			\
-	case 4: __get_user_asm("lw", ptr); break;			\
-	case 8: __GET_USER_DW(ptr); break;				\
-	default: __get_user_unknown(); break;				\
-	}								\
-	(x) = (__typeof__(*(ptr))) __gu_val;				\
+	__get_user_common((x), size, ptr);				\
 	__gu_err;							\
 })
 
 #define __get_user_check(x,ptr,size)					\
 ({									\
-	const __typeof__(*(ptr)) __user * __gu_addr = (ptr);		\
-	__typeof__(*(ptr)) __gu_val = 0;				\
 	long __gu_err = -EFAULT;					\
+	const void __user * __gu_ptr = (ptr);				\
 									\
-	if (likely(access_ok(VERIFY_READ,  __gu_addr, size))) {		\
-		switch (size) {						\
-		case 1: __get_user_asm("lb", __gu_addr); break;		\
-		case 2: __get_user_asm("lh", __gu_addr); break;		\
-		case 4: __get_user_asm("lw", __gu_addr); break;		\
-		case 8: __GET_USER_DW(__gu_addr); break;		\
-		default: __get_user_unknown(); break;			\
-		}							\
-	}								\
-	(x) = (__typeof__(*(ptr))) __gu_val;				\
+	if (likely(access_ok(VERIFY_READ,  __gu_ptr, size)))		\
+		__get_user_common((x), size, __gu_ptr);			\
+									\
 	__gu_err;							\
 })
 
-#define __get_user_asm(insn, addr)					\
+#define __get_user_asm(val, insn, addr)					\
 {									\
+	long __gu_tmp;							\
+									\
 	__asm__ __volatile__(						\
 	"1:	" insn "	%1, %3				\n"	\
 	"2:							\n"	\
@@ -255,14 +255,16 @@
 	"	.section __ex_table,\"a\"			\n"	\
 	"	"__UA_ADDR "\t1b, 3b				\n"	\
 	"	.previous					\n"	\
-	: "=r" (__gu_err), "=r" (__gu_val)				\
+	: "=r" (__gu_err), "=r" (__gu_tmp)				\
 	: "0" (0), "o" (__m(addr)), "i" (-EFAULT));			\
+									\
+	(val) = (__typeof__(val)) __gu_tmp;				\
 }
 
 /*
  * Get a long long 64 using 32 bit registers.
  */
-#define __get_user_asm_ll32(addr)					\
+#define __get_user_asm_ll32(val, addr)					\
 {									\
 	__asm__ __volatile__(						\
 	"1:	lw	%1, (%3)				\n"	\
@@ -278,21 +280,20 @@
 	"	" __UA_ADDR "	1b, 4b				\n"	\
 	"	" __UA_ADDR "	2b, 4b				\n"	\
 	"	.previous					\n"	\
-	: "=r" (__gu_err), "=&r" (__gu_val)				\
+	: "=r" (__gu_err), "=&r" (val)					\
 	: "0" (0), "r" (addr), "i" (-EFAULT));				\
 }
 
-extern void __get_user_unknown(void);
-
 /*
  * Yuck.  We need two variants, one for 64bit operation and one
  * for 32 bit mode and old iron.
  */
-#ifdef __mips64
-#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
-#else
+#ifdef CONFIG_32BIT
 #define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
 #endif
+#ifdef CONFIG_64BIT
+#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
+#endif
 
 #define __put_user_nocheck(x,ptr,size)					\
 ({									\
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index 89ea8b6..e7ff9b1 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -307,17 +307,33 @@
 #define __NR_inotify_init		(__NR_Linux + 284)
 #define __NR_inotify_add_watch		(__NR_Linux + 285)
 #define __NR_inotify_rm_watch		(__NR_Linux + 286)
-
+#define __NR_migrate_pages		(__NR_Linux + 287)
+#define __NR_openat			(__NR_Linux + 288)
+#define __NR_mkdirat			(__NR_Linux + 289)
+#define __NR_mknodat			(__NR_Linux + 290)
+#define __NR_fchownat			(__NR_Linux + 291)
+#define __NR_futimesat			(__NR_Linux + 292)
+#define __NR_newfstatat			(__NR_Linux + 293)
+#define __NR_unlinkat			(__NR_Linux + 294)
+#define __NR_renameat			(__NR_Linux + 295)
+#define __NR_linkat			(__NR_Linux + 296)
+#define __NR_symlinkat			(__NR_Linux + 297)
+#define __NR_readlinkat			(__NR_Linux + 298)
+#define __NR_fchmodat			(__NR_Linux + 299)
+#define __NR_faccessat			(__NR_Linux + 300)
+#define __NR_pselect6			(__NR_Linux + 301)
+#define __NR_ppoll			(__NR_Linux + 302)
+#define __NR_unshare			(__NR_Linux + 303)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls		286
+#define __NR_Linux_syscalls		303
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		283
+#define __NR_O32_Linux_syscalls		303
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -571,16 +587,33 @@
 #define __NR_inotify_init		(__NR_Linux + 243)
 #define __NR_inotify_add_watch		(__NR_Linux + 244)
 #define __NR_inotify_rm_watch		(__NR_Linux + 245)
+#define __NR_migrate_pages		(__NR_Linux + 246)
+#define __NR_openat			(__NR_Linux + 247)
+#define __NR_mkdirat			(__NR_Linux + 248)
+#define __NR_mknodat			(__NR_Linux + 249)
+#define __NR_fchownat			(__NR_Linux + 250)
+#define __NR_futimesat			(__NR_Linux + 251)
+#define __NR_newfstatat			(__NR_Linux + 252)
+#define __NR_unlinkat			(__NR_Linux + 253)
+#define __NR_renameat			(__NR_Linux + 254)
+#define __NR_linkat			(__NR_Linux + 255)
+#define __NR_symlinkat			(__NR_Linux + 256)
+#define __NR_readlinkat			(__NR_Linux + 257)
+#define __NR_fchmodat			(__NR_Linux + 258)
+#define __NR_faccessat			(__NR_Linux + 259)
+#define __NR_pselect6			(__NR_Linux + 260)
+#define __NR_ppoll			(__NR_Linux + 261)
+#define __NR_unshare			(__NR_Linux + 262)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls		245
+#define __NR_Linux_syscalls		262
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		242
+#define __NR_64_Linux_syscalls		262
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -838,16 +871,33 @@
 #define __NR_inotify_init		(__NR_Linux + 247)
 #define __NR_inotify_add_watch		(__NR_Linux + 248)
 #define __NR_inotify_rm_watch		(__NR_Linux + 249)
+#define __NR_migrate_pages		(__NR_Linux + 250)
+#define __NR_openat			(__NR_Linux + 251)
+#define __NR_mkdirat			(__NR_Linux + 252)
+#define __NR_mknodat			(__NR_Linux + 253)
+#define __NR_fchownat			(__NR_Linux + 254)
+#define __NR_futimesat			(__NR_Linux + 255)
+#define __NR_newfstatat			(__NR_Linux + 256)
+#define __NR_unlinkat			(__NR_Linux + 257)
+#define __NR_renameat			(__NR_Linux + 258)
+#define __NR_linkat			(__NR_Linux + 259)
+#define __NR_symlinkat			(__NR_Linux + 260)
+#define __NR_readlinkat			(__NR_Linux + 261)
+#define __NR_fchmodat			(__NR_Linux + 262)
+#define __NR_faccessat			(__NR_Linux + 263)
+#define __NR_pselect6			(__NR_Linux + 264)
+#define __NR_ppoll			(__NR_Linux + 265)
+#define __NR_unshare			(__NR_Linux + 266)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls		249
+#define __NR_Linux_syscalls		266
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		246
+#define __NR_N32_Linux_syscalls		266
 
 #ifndef __ASSEMBLY__
 
diff --git a/include/asm-powerpc/compat.h b/include/asm-powerpc/compat.h
index accb80c..aacaabd 100644
--- a/include/asm-powerpc/compat.h
+++ b/include/asm-powerpc/compat.h
@@ -126,6 +126,11 @@
 	return (void __user *)(unsigned long)uptr;
 }
 
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+	return (u32)(unsigned long)uptr;
+}
+
 static inline void __user *compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = current->thread.regs;
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 837756a..2ac63f5 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -15,7 +15,6 @@
 #include <linux/mm.h>
 #include <asm/scatterlist.h>
 #include <asm/io.h>
-#include <asm/bug.h>
 
 #define DMA_ERROR_CODE		(~(dma_addr_t)0x0)
 
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 5b2bd4e..cbd297f 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -222,5 +222,7 @@
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
 
+extern void kdump_move_device_tree(void);
+
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
index 82ce476..2dc9363 100644
--- a/include/asm-powerpc/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -521,6 +521,11 @@
 extern struct smu_sdbp_header *smu_get_sdb_partition(int id,
 					unsigned int *size);
 
+/* Get "sdb" partition data from an SMU satellite */
+extern struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id,
+					int id, unsigned int *size);
+
+
 #endif /* __KERNEL__ */
 
 
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index 67cdaf3..c044ec1 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -37,7 +37,7 @@
 	int		preempt_count;		/* 0 => preemptable,
 						   <0 => BUG */
 	struct restart_block restart_block;
-	void *nvgprs_frame;
+	void __user *nvgprs_frame;
 	/* low level flags - has atomic operations done on it */
 	unsigned long	flags ____cacheline_aligned_in_smp;
 };
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h
index be104f2..0b7c0ca 100644
--- a/include/asm-s390/uaccess.h
+++ b/include/asm-s390/uaccess.h
@@ -61,7 +61,7 @@
 #define segment_eq(a,b) ((a).ar4 == (b).ar4)
 
 
-static inline int __access_ok(const void *addr, unsigned long size)
+static inline int __access_ok(const void __user *addr, unsigned long size)
 {
 	return 1;
 }
@@ -208,25 +208,25 @@
 	case 1: {						\
 		unsigned char __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = *(__typeof__(*(ptr)) *) &__x;		\
+		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 2: {						\
 		unsigned short __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = *(__typeof__(*(ptr)) *) &__x;		\
+		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 4: {						\
 		unsigned int __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = *(__typeof__(*(ptr)) *) &__x;		\
+		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	case 8: {						\
 		unsigned long long __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = *(__typeof__(*(ptr)) *) &__x;		\
+		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
 		break;						\
 	};							\
 	default:						\
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 2ac64e6..0615d60 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -315,11 +315,12 @@
 #define __NR_faccessat		296
 #define __NR_pselect6		297
 #define __NR_ppoll		298
+#define __NR_unshare		299
 
-/* WARNING: You MAY NOT add syscall numbers larger than 298, since
+/* WARNING: You MAY NOT add syscall numbers larger than 299, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 298 entries (starting at zero).  Therefore
- *          find a free slot in the 0-298 range.
+ *          sized to have 299 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-299 range.
  */
 
 #define _syscall0(type,name) \
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 84ac2bd..c58ba8a 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -317,11 +317,12 @@
 #define __NR_faccessat		296
 #define __NR_pselect6		297
 #define __NR_ppoll		298
+#define __NR_unshare		299
 
-/* WARNING: You MAY NOT add syscall numbers larger than 298, since
+/* WARNING: You MAY NOT add syscall numbers larger than 299, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 298 entries (starting at zero).  Therefore
- *          find a free slot in the 0-298 range.
+ *          sized to have 299 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-299 range.
  */
 
 #define _syscall0(type,name) \
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h
index 4f6a4dc..bdbd893 100644
--- a/include/asm-x86_64/apic.h
+++ b/include/asm-x86_64/apic.h
@@ -17,6 +17,7 @@
 #define APIC_DEBUG   2
 
 extern int apic_verbosity;
+extern int apic_runs_main_timer;
 
 /*
  * Define the default level of output to be very little
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
index 41c0ac8..76bb619 100644
--- a/include/asm-x86_64/cpufeature.h
+++ b/include/asm-x86_64/cpufeature.h
@@ -61,7 +61,7 @@
 #define X86_FEATURE_K6_MTRR	(3*32+ 1) /* AMD K6 nonstandard MTRRs */
 #define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
 #define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
-/* 4 free */
+#define X86_FEATURE_REP_GOOD	(3*32+ 4) /* rep microcode works well on this CPU */
 #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
 #define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
 
diff --git a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h
index 8661b47..8689951 100644
--- a/include/asm-x86_64/hardirq.h
+++ b/include/asm-x86_64/hardirq.h
@@ -16,23 +16,6 @@
 #define set_softirq_pending(x) write_pda(__softirq_pending, (x))
 #define or_softirq_pending(x)  or_pda(__softirq_pending, (x))
 
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-static inline void ack_bad_irq(unsigned int irq)
-{
-	printk("unexpected IRQ trap at vector %02x\n", irq);
-#ifdef CONFIG_X86_LOCAL_APIC
-	/*
-	 * Currently unexpected vectors happen only on SMP and APIC.
-	 * We _must_ ack these because every local APIC has only N
-	 * irq slots per priority level, and a 'hanging, unacked' IRQ
-	 * holds up an irq slot - in excessive cases (when multiple
-	 * unexpected vectors occur) that might lock up the APIC
-	 * completely.
-	 */
-	ack_APIC_irq();
-#endif
-}
+extern void ack_bad_irq(unsigned int irq);
+
 #endif /* __ASM_HARDIRQ_H */
diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h
index 34e434c..dffe276 100644
--- a/include/asm-x86_64/numa.h
+++ b/include/asm-x86_64/numa.h
@@ -22,8 +22,15 @@
 extern unsigned char apicid_to_node[256];
 #ifdef CONFIG_NUMA
 extern void __init init_cpu_to_node(void);
+
+static inline void clear_node_cpumask(int cpu)
+{
+	clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
+}
+
 #else
 #define init_cpu_to_node() do {} while (0)
+#define clear_node_cpumask(cpu) do {} while (0)
 #endif
 
 #define NUMA_NO_NODE 0xff
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index 115e496..c99832e 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -41,10 +41,18 @@
 
 extern void time_init_gtod(void);
 extern int pmtimer_mark_offset(void);
+extern void pmtimer_resume(void);
+extern void pmtimer_wait(unsigned);
 extern unsigned int do_gettimeoffset_pm(void);
+#ifdef CONFIG_X86_PM_TIMER
 extern u32 pmtmr_ioport;
+#else
+#define pmtmr_ioport 0
+#endif
 extern unsigned long long monotonic_base;
 extern int sysctl_vsyscall;
+extern int nohpet;
+extern unsigned long vxtime_hz;
 
 extern void do_softirq_thunk(void);
 
@@ -65,6 +73,9 @@
 
 extern void load_gs_index(unsigned gs);
 
+extern void stop_timer_interrupt(void);
+extern void main_timer_handler(struct pt_regs *regs);
+
 extern unsigned long end_pfn_map; 
 
 extern void show_trace(unsigned long * rsp);
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index a73f0c7..b7f6603 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -327,7 +327,7 @@
 #define wmb()	asm volatile("" ::: "memory")
 #endif
 #define read_barrier_depends()	do {} while(0)
-#define set_mb(var, value) do { xchg(&var, value); } while (0)
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 
 #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 13e9f4a..20b446f 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -84,7 +84,6 @@
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <linux/bitmap.h>
-#include <asm/bug.h>
 
 typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
 extern cpumask_t _unused_cpumask_arg_;
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index a3f0994..4361f37 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -8,7 +8,6 @@
 #include <linux/spinlock.h>
 #include <linux/cache.h>
 #include <linux/rcupdate.h>
-#include <asm/bug.h>
 
 struct nameidata;
 struct vfsmount;
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h
index b1999bf..b81e58b 100644
--- a/include/linux/dvb/video.h
+++ b/include/linux/dvb/video.h
@@ -135,7 +135,7 @@
 
 typedef struct video_spu_palette {      /* SPU Palette information */
 	int length;
-	uint8_t *palette;
+	uint8_t __user *palette;
 } video_spu_palette_t;
 
 
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 23fe746..18cf1f3 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -82,6 +82,7 @@
 extern void elv_dispatch_sort(request_queue_t *, struct request *);
 extern void elv_add_request(request_queue_t *, struct request *, int, int);
 extern void __elv_add_request(request_queue_t *, struct request *, int, int);
+extern void elv_insert(request_queue_t *, struct request *, int);
 extern int elv_merge(request_queue_t *, struct request **, struct bio *);
 extern void elv_merge_requests(request_queue_t *, struct request *,
 			       struct request *);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 7863a59..63f1d63 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -100,6 +100,9 @@
 /* Returns the number of read bytes */
 extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
 					 u8 command, u8 *values);
+extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
+					  u8 command, u8 length,
+					  u8 *values);
 
 /*
  * A driver is capable of handling one or more physical devices present on
diff --git a/include/linux/ioc3.h b/include/linux/ioc3.h
index e7906a7..da7c09e 100644
--- a/include/linux/ioc3.h
+++ b/include/linux/ioc3.h
@@ -27,7 +27,7 @@
 	int id;				/* IOC3 sequence number */
 	/* PCI mapping */
 	unsigned long pma;		/* physical address */
-	struct __iomem ioc3 *vma;	/* pointer to registers */
+	struct ioc3 __iomem *vma;	/* pointer to registers */
 	struct pci_dev *pdev;		/* PCI device */
 	/* IRQ stuff */
 	int dual_irq;			/* set if separate IRQs are used */
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 558cb4c..0fe4aa8 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -23,6 +23,7 @@
 #define jfs_debug jbd_debug
 #else
 
+#include <linux/types.h>
 #include <linux/buffer_head.h>
 #include <linux/journal-head.h>
 #include <linux/stddef.h>
@@ -238,7 +239,6 @@
 
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <asm/bug.h>
 
 #define JBD_ASSERTIONS
 #ifdef JBD_ASSERTIONS
@@ -618,6 +618,7 @@
  * @j_wbuf: array of buffer_heads for journal_commit_transaction
  * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
  *	number that will fit in j_blocksize
+ * @j_last_sync_writer: most recent pid which did a synchronous write
  * @j_private: An opaque pointer to fs-private information.
  */
 
@@ -807,6 +808,8 @@
 	struct buffer_head	**j_wbuf;
 	int			j_wbufsize;
 
+	pid_t			j_last_sync_writer;
+
 	/*
 	 * An opaque pointer to fs-private information.  ext3 puts its
 	 * superblock pointer here
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 85854b8..75e9f07 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -303,7 +303,7 @@
  */
 #define put_page_testzero(p)				\
 	({						\
-		BUG_ON(page_count(p) == 0);		\
+		BUG_ON(atomic_read(&(p)->_count) == -1);\
 		atomic_add_negative(-1, &(p)->_count);	\
 	})
 
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index fedfbc8..7dfd6e1 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -15,7 +15,6 @@
 #include <asm/unaligned.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/bug.h>
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
 #define map_bankwidth(map) 1
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 6731977..3abc8e3 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -15,6 +15,7 @@
 
 extern int copy_namespace(int, struct task_struct *);
 extern void __put_namespace(struct namespace *namespace);
+extern struct namespace *dup_namespace(struct task_struct *, struct fs_struct *);
 
 static inline void put_namespace(struct namespace *namespace)
 {
diff --git a/include/linux/netfilter_ipv4/ipt_connbytes.h b/include/linux/netfilter_ipv4/ipt_connbytes.h
index b04dfa3..f63e6ee 100644
--- a/include/linux/netfilter_ipv4/ipt_connbytes.h
+++ b/include/linux/netfilter_ipv4/ipt_connbytes.h
@@ -1,10 +1,10 @@
 #ifndef _IPT_CONNBYTES_H
 #define _IPT_CONNBYTES_H
 
-#include <net/netfilter/xt_connbytes.h>
+#include <linux/netfilter/xt_connbytes.h>
 #define ipt_connbytes_what xt_connbytes_what
 
-#define IPT_CONNBYTES_PKTS	XT_CONNBYTES_PACKETS
+#define IPT_CONNBYTES_PKTS	XT_CONNBYTES_PKTS
 #define IPT_CONNBYTES_BYTES	XT_CONNBYTES_BYTES
 #define IPT_CONNBYTES_AVGPKT	XT_CONNBYTES_AVGPKT
 
diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h
index 7fd1bec..a3f6eff 100644
--- a/include/linux/netfilter_ipv4/ipt_policy.h
+++ b/include/linux/netfilter_ipv4/ipt_policy.h
@@ -27,16 +27,22 @@
 			reqid:1;
 };
 
+union ipt_policy_addr
+{
+	struct in_addr	a4;
+	struct in6_addr	a6;
+};
+
 struct ipt_policy_elem
 {
-	u_int32_t	saddr;
-	u_int32_t	smask;
-	u_int32_t	daddr;
-	u_int32_t	dmask;
-	u_int32_t	spi;
-	u_int32_t	reqid;
-	u_int8_t	proto;
-	u_int8_t	mode;
+	union ipt_policy_addr	saddr;
+	union ipt_policy_addr	smask;
+	union ipt_policy_addr	daddr;
+	union ipt_policy_addr	dmask;
+	u_int32_t		spi;
+	u_int32_t		reqid;
+	u_int8_t		proto;
+	u_int8_t		mode;
 
 	struct ipt_policy_spec	match;
 	struct ipt_policy_spec	invert;
diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h
index 5a93afc..671bd81 100644
--- a/include/linux/netfilter_ipv6/ip6t_policy.h
+++ b/include/linux/netfilter_ipv6/ip6t_policy.h
@@ -27,16 +27,22 @@
 			reqid:1;
 };
 
+union ip6t_policy_addr
+{
+	struct in_addr	a4;
+	struct in6_addr	a6;
+};
+
 struct ip6t_policy_elem
 {
-	struct in6_addr	saddr;
-	struct in6_addr	smask;
-	struct in6_addr	daddr;
-	struct in6_addr	dmask;
-	u_int32_t	spi;
-	u_int32_t	reqid;
-	u_int8_t	proto;
-	u_int8_t	mode;
+	union ip6t_policy_addr	saddr;
+	union ip6t_policy_addr	smask;
+	union ip6t_policy_addr	daddr;
+	union ip6t_policy_addr	dmask;
+	u_int32_t		spi;
+	u_int32_t		reqid;
+	u_int8_t		proto;
+	u_int8_t		mode;
 
 	struct ip6t_policy_spec	match;
 	struct ip6t_policy_spec	invert;
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 4726ef7..b959a45 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -84,7 +84,6 @@
 #include <linux/threads.h>
 #include <linux/bitmap.h>
 #include <linux/numa.h>
-#include <asm/bug.h>
 
 typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
 extern nodemask_t _unused_nodemask_arg_;
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
index 2c177e4..8a94c71 100644
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -114,7 +114,7 @@
 
 struct packet_settings
 {
-	__u8			size;		/* packet size in (512 byte) sectors */
+	__u32			size;		/* packet size in (512 byte) sectors */
 	__u8			fp;		/* fixed packets */
 	__u8			link_loss;	/* the rest is specified
 						 * as per Mt Fuji */
@@ -169,8 +169,8 @@
 #if (PAGE_SIZE % CD_FRAMESIZE) != 0
 #error "PAGE_SIZE must be a multiple of CD_FRAMESIZE"
 #endif
-#define PACKET_MAX_SIZE		32
-#define PAGES_PER_PACKET	(PACKET_MAX_SIZE * CD_FRAMESIZE / PAGE_SIZE)
+#define PACKET_MAX_SIZE		128
+#define FRAMES_PER_PAGE		(PAGE_SIZE / CD_FRAMESIZE)
 #define PACKET_MAX_SECTORS	(PACKET_MAX_SIZE * CD_FRAMESIZE >> 9)
 
 enum packet_data_state {
@@ -219,7 +219,7 @@
 	atomic_t		io_errors;	/* Number of read/write errors during IO */
 
 	struct bio		*r_bios[PACKET_MAX_SIZE]; /* bios to use during data gathering */
-	struct page		*pages[PAGES_PER_PACKET];
+	struct page		*pages[PACKET_MAX_SIZE / FRAMES_PER_PAGE];
 
 	int			cache_valid;	/* If non-zero, the data for the zone defined */
 						/* by the sector variable is completely cached */
diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h
index 0a36050..806ec5b 100644
--- a/include/linux/reiserfs_acl.h
+++ b/include/linux/reiserfs_acl.h
@@ -58,9 +58,13 @@
 extern struct reiserfs_xattr_handler posix_acl_access_handler;
 #else
 
-#define reiserfs_get_acl NULL
 #define reiserfs_cache_default_acl(inode) 0
 
+static inline struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
+{
+	return NULL;
+}
+
 static inline int reiserfs_xattr_posix_acl_init(void)
 {
 	return 0;
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 9dfa3ee..44153fd 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -17,7 +17,6 @@
 #include <linux/compiler.h>
 #include <linux/thread_info.h>
 #include <asm/smp.h>
-#include <asm/bug.h>
 
 /*
  * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc.
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 43bcd13..37c1c76 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -42,13 +42,21 @@
 #ifdef CONFIG_PM
 /* kernel/power/swsusp.c */
 extern int software_suspend(void);
+
+#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+extern int pm_prepare_console(void);
+extern void pm_restore_console(void);
+#else
+static inline int pm_prepare_console(void) { return 0; }
+static inline void pm_restore_console(void) {}
+#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */
 #else
 static inline int software_suspend(void)
 {
 	printk("Warning: fake suspend called\n");
 	return -EPERM;
 }
-#endif
+#endif /* CONFIG_PM */
 
 #ifdef CONFIG_SUSPEND_SMP
 extern void disable_nonboot_cpus(void);
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 6f6c697..5208b12d 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -549,7 +549,7 @@
 struct v4l2_clip
 {
 	struct v4l2_rect        c;
-	struct v4l2_clip	*next;
+	struct v4l2_clip	__user *next;
 };
 
 struct v4l2_window
@@ -629,6 +629,7 @@
 #define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
 #define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
 #define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)
 
 #define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
 #define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
@@ -661,7 +662,8 @@
 				 V4L2_STD_PAL_H		|\
 				 V4L2_STD_PAL_I)
 #define V4L2_STD_NTSC           (V4L2_STD_NTSC_M	|\
-				 V4L2_STD_NTSC_M_JP)
+				 V4L2_STD_NTSC_M_JP     |\
+				 V4L2_STD_NTSC_M_KR)
 #define V4L2_STD_SECAM_DK      	(V4L2_STD_SECAM_D	|\
 				 V4L2_STD_SECAM_K	|\
 				 V4L2_STD_SECAM_K1)
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 67856eb..dac43b1 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -88,12 +88,6 @@
 extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
 extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
 
-static inline struct nf_conntrack_l3proto *
-__nf_ct_l3proto_find(u_int16_t l3proto)
-{
-	return nf_ct_l3protos[l3proto];
-}
-
 extern struct nf_conntrack_l3proto *
 nf_ct_l3proto_find_get(u_int16_t l3proto);
 
@@ -103,4 +97,13 @@
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
 extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
+
+static inline struct nf_conntrack_l3proto *
+__nf_ct_l3proto_find(u_int16_t l3proto)
+{
+	if (unlikely(l3proto >= AF_MAX))
+		return &nf_conntrack_generic_l3proto;
+	return nf_ct_l3protos[l3proto];
+}
+
 #endif /*_NF_CONNTRACK_L3PROTO_H*/
diff --git a/init/Kconfig b/init/Kconfig
index 8b7abae..38416a1 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -169,7 +169,6 @@
 config AUDIT
 	bool "Auditing support"
 	depends on NET
-	default y if SECURITY_SELINUX
 	help
 	  Enable auditing infrastructure that can be used with another
 	  kernel subsystem, such as SELinux (which requires this for
diff --git a/kernel/compat.c b/kernel/compat.c
index 1867290..8c9cd88b 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -23,7 +23,6 @@
 #include <linux/security.h>
 
 #include <asm/uaccess.h>
-#include <asm/bug.h>
 
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
diff --git a/kernel/fork.c b/kernel/fork.c
index 7f0ab5e..8e88b37 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -446,6 +446,55 @@
 	}
 }
 
+/*
+ * Allocate a new mm structure and copy contents from the
+ * mm structure of the passed in task structure.
+ */
+static struct mm_struct *dup_mm(struct task_struct *tsk)
+{
+	struct mm_struct *mm, *oldmm = current->mm;
+	int err;
+
+	if (!oldmm)
+		return NULL;
+
+	mm = allocate_mm();
+	if (!mm)
+		goto fail_nomem;
+
+	memcpy(mm, oldmm, sizeof(*mm));
+
+	if (!mm_init(mm))
+		goto fail_nomem;
+
+	if (init_new_context(tsk, mm))
+		goto fail_nocontext;
+
+	err = dup_mmap(mm, oldmm);
+	if (err)
+		goto free_pt;
+
+	mm->hiwater_rss = get_mm_rss(mm);
+	mm->hiwater_vm = mm->total_vm;
+
+	return mm;
+
+free_pt:
+	mmput(mm);
+
+fail_nomem:
+	return NULL;
+
+fail_nocontext:
+	/*
+	 * If init_new_context() failed, we cannot use mmput() to free the mm
+	 * because it calls destroy_context()
+	 */
+	mm_free_pgd(mm);
+	free_mm(mm);
+	return NULL;
+}
+
 static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
 {
 	struct mm_struct * mm, *oldmm;
@@ -473,43 +522,17 @@
 	}
 
 	retval = -ENOMEM;
-	mm = allocate_mm();
+	mm = dup_mm(tsk);
 	if (!mm)
 		goto fail_nomem;
 
-	/* Copy the current MM stuff.. */
-	memcpy(mm, oldmm, sizeof(*mm));
-	if (!mm_init(mm))
-		goto fail_nomem;
-
-	if (init_new_context(tsk,mm))
-		goto fail_nocontext;
-
-	retval = dup_mmap(mm, oldmm);
-	if (retval)
-		goto free_pt;
-
-	mm->hiwater_rss = get_mm_rss(mm);
-	mm->hiwater_vm = mm->total_vm;
-
 good_mm:
 	tsk->mm = mm;
 	tsk->active_mm = mm;
 	return 0;
 
-free_pt:
-	mmput(mm);
 fail_nomem:
 	return retval;
-
-fail_nocontext:
-	/*
-	 * If init_new_context() failed, we cannot use mmput() to free the mm
-	 * because it calls destroy_context()
-	 */
-	mm_free_pgd(mm);
-	free_mm(mm);
-	return retval;
 }
 
 static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
@@ -597,32 +620,17 @@
 	return newf;
 }
 
-static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+/*
+ * Allocate a new files structure and copy contents from the
+ * passed in files structure.
+ */
+static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
 {
-	struct files_struct *oldf, *newf;
+	struct files_struct *newf;
 	struct file **old_fds, **new_fds;
-	int open_files, size, i, error = 0, expand;
+	int open_files, size, i, expand;
 	struct fdtable *old_fdt, *new_fdt;
 
-	/*
-	 * A background process may not have any files ...
-	 */
-	oldf = current->files;
-	if (!oldf)
-		goto out;
-
-	if (clone_flags & CLONE_FILES) {
-		atomic_inc(&oldf->count);
-		goto out;
-	}
-
-	/*
-	 * Note: we may be using current for both targets (See exec.c)
-	 * This works because we cache current->files (old) as oldf. Don't
-	 * break this.
-	 */
-	tsk->files = NULL;
-	error = -ENOMEM;
 	newf = alloc_files();
 	if (!newf)
 		goto out;
@@ -651,9 +659,9 @@
 	if (expand) {
 		spin_unlock(&oldf->file_lock);
 		spin_lock(&newf->file_lock);
-		error = expand_files(newf, open_files-1);
+		*errorp = expand_files(newf, open_files-1);
 		spin_unlock(&newf->file_lock);
-		if (error < 0)
+		if (*errorp < 0)
 			goto out_release;
 		new_fdt = files_fdtable(newf);
 		/*
@@ -702,10 +710,8 @@
 		memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
 	}
 
-	tsk->files = newf;
-	error = 0;
 out:
-	return error;
+	return newf;
 
 out_release:
 	free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset);
@@ -715,6 +721,40 @@
 	goto out;
 }
 
+static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+{
+	struct files_struct *oldf, *newf;
+	int error = 0;
+
+	/*
+	 * A background process may not have any files ...
+	 */
+	oldf = current->files;
+	if (!oldf)
+		goto out;
+
+	if (clone_flags & CLONE_FILES) {
+		atomic_inc(&oldf->count);
+		goto out;
+	}
+
+	/*
+	 * Note: we may be using current for both targets (See exec.c)
+	 * This works because we cache current->files (old) as oldf. Don't
+	 * break this.
+	 */
+	tsk->files = NULL;
+	error = -ENOMEM;
+	newf = dup_fd(oldf, &error);
+	if (!newf)
+		goto out;
+
+	tsk->files = newf;
+	error = 0;
+out:
+	return error;
+}
+
 /*
  *	Helper to unshare the files of the current task.
  *	We don't want to expose copy_files internals to
@@ -1323,3 +1363,249 @@
 			sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
 			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
 }
+
+
+/*
+ * Check constraints on flags passed to the unshare system call and
+ * force unsharing of additional process context as appropriate.
+ */
+static inline void check_unshare_flags(unsigned long *flags_ptr)
+{
+	/*
+	 * If unsharing a thread from a thread group, must also
+	 * unshare vm.
+	 */
+	if (*flags_ptr & CLONE_THREAD)
+		*flags_ptr |= CLONE_VM;
+
+	/*
+	 * If unsharing vm, must also unshare signal handlers.
+	 */
+	if (*flags_ptr & CLONE_VM)
+		*flags_ptr |= CLONE_SIGHAND;
+
+	/*
+	 * If unsharing signal handlers and the task was created
+	 * using CLONE_THREAD, then must unshare the thread
+	 */
+	if ((*flags_ptr & CLONE_SIGHAND) &&
+	    (atomic_read(&current->signal->count) > 1))
+		*flags_ptr |= CLONE_THREAD;
+
+	/*
+	 * If unsharing namespace, must also unshare filesystem information.
+	 */
+	if (*flags_ptr & CLONE_NEWNS)
+		*flags_ptr |= CLONE_FS;
+}
+
+/*
+ * Unsharing of tasks created with CLONE_THREAD is not supported yet
+ */
+static int unshare_thread(unsigned long unshare_flags)
+{
+	if (unshare_flags & CLONE_THREAD)
+		return -EINVAL;
+
+	return 0;
+}
+
+/*
+ * Unshare the filesystem structure if it is being shared
+ */
+static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+{
+	struct fs_struct *fs = current->fs;
+
+	if ((unshare_flags & CLONE_FS) &&
+	    (fs && atomic_read(&fs->count) > 1)) {
+		*new_fsp = __copy_fs_struct(current->fs);
+		if (!*new_fsp)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/*
+ * Unshare the namespace structure if it is being shared
+ */
+static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
+{
+	struct namespace *ns = current->namespace;
+
+	if ((unshare_flags & CLONE_NEWNS) &&
+	    (ns && atomic_read(&ns->count) > 1)) {
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		*new_nsp = dup_namespace(current, new_fs ? new_fs : current->fs);
+		if (!*new_nsp)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/*
+ * Unsharing of sighand for tasks created with CLONE_SIGHAND is not
+ * supported yet
+ */
+static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
+{
+	struct sighand_struct *sigh = current->sighand;
+
+	if ((unshare_flags & CLONE_SIGHAND) &&
+	    (sigh && atomic_read(&sigh->count) > 1))
+		return -EINVAL;
+	else
+		return 0;
+}
+
+/*
+ * Unshare vm if it is being shared
+ */
+static int unshare_vm(unsigned long unshare_flags, struct mm_struct **new_mmp)
+{
+	struct mm_struct *mm = current->mm;
+
+	if ((unshare_flags & CLONE_VM) &&
+	    (mm && atomic_read(&mm->mm_users) > 1)) {
+		*new_mmp = dup_mm(current);
+		if (!*new_mmp)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/*
+ * Unshare file descriptor table if it is being shared
+ */
+static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
+{
+	struct files_struct *fd = current->files;
+	int error = 0;
+
+	if ((unshare_flags & CLONE_FILES) &&
+	    (fd && atomic_read(&fd->count) > 1)) {
+		*new_fdp = dup_fd(fd, &error);
+		if (!*new_fdp)
+			return error;
+	}
+
+	return 0;
+}
+
+/*
+ * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not
+ * supported yet
+ */
+static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp)
+{
+	if (unshare_flags & CLONE_SYSVSEM)
+		return -EINVAL;
+
+	return 0;
+}
+
+/*
+ * unshare allows a process to 'unshare' part of the process
+ * context which was originally shared using clone.  copy_*
+ * functions used by do_fork() cannot be used here directly
+ * because they modify an inactive task_struct that is being
+ * constructed. Here we are modifying the current, active,
+ * task_struct.
+ */
+asmlinkage long sys_unshare(unsigned long unshare_flags)
+{
+	int err = 0;
+	struct fs_struct *fs, *new_fs = NULL;
+	struct namespace *ns, *new_ns = NULL;
+	struct sighand_struct *sigh, *new_sigh = NULL;
+	struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
+	struct files_struct *fd, *new_fd = NULL;
+	struct sem_undo_list *new_ulist = NULL;
+
+	check_unshare_flags(&unshare_flags);
+
+	if ((err = unshare_thread(unshare_flags)))
+		goto bad_unshare_out;
+	if ((err = unshare_fs(unshare_flags, &new_fs)))
+		goto bad_unshare_cleanup_thread;
+	if ((err = unshare_namespace(unshare_flags, &new_ns, new_fs)))
+		goto bad_unshare_cleanup_fs;
+	if ((err = unshare_sighand(unshare_flags, &new_sigh)))
+		goto bad_unshare_cleanup_ns;
+	if ((err = unshare_vm(unshare_flags, &new_mm)))
+		goto bad_unshare_cleanup_sigh;
+	if ((err = unshare_fd(unshare_flags, &new_fd)))
+		goto bad_unshare_cleanup_vm;
+	if ((err = unshare_semundo(unshare_flags, &new_ulist)))
+		goto bad_unshare_cleanup_fd;
+
+	if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) {
+
+		task_lock(current);
+
+		if (new_fs) {
+			fs = current->fs;
+			current->fs = new_fs;
+			new_fs = fs;
+		}
+
+		if (new_ns) {
+			ns = current->namespace;
+			current->namespace = new_ns;
+			new_ns = ns;
+		}
+
+		if (new_sigh) {
+			sigh = current->sighand;
+			current->sighand = new_sigh;
+			new_sigh = sigh;
+		}
+
+		if (new_mm) {
+			mm = current->mm;
+			active_mm = current->active_mm;
+			current->mm = new_mm;
+			current->active_mm = new_mm;
+			activate_mm(active_mm, new_mm);
+			new_mm = mm;
+		}
+
+		if (new_fd) {
+			fd = current->files;
+			current->files = new_fd;
+			new_fd = fd;
+		}
+
+		task_unlock(current);
+	}
+
+bad_unshare_cleanup_fd:
+	if (new_fd)
+		put_files_struct(new_fd);
+
+bad_unshare_cleanup_vm:
+	if (new_mm)
+		mmput(new_mm);
+
+bad_unshare_cleanup_sigh:
+	if (new_sigh)
+		if (atomic_dec_and_test(&new_sigh->count))
+			kmem_cache_free(sighand_cachep, new_sigh);
+
+bad_unshare_cleanup_ns:
+	if (new_ns)
+		put_namespace(new_ns);
+
+bad_unshare_cleanup_fs:
+	if (new_fs)
+		put_fs_struct(new_fs);
+
+bad_unshare_cleanup_thread:
+bad_unshare_out:
+	return err;
+}
diff --git a/kernel/intermodule.c b/kernel/intermodule.c
index 0cbe633..55b1e5b 100644
--- a/kernel/intermodule.c
+++ b/kernel/intermodule.c
@@ -179,3 +179,6 @@
 EXPORT_SYMBOL(inter_module_unregister);
 EXPORT_SYMBOL(inter_module_get_request);
 EXPORT_SYMBOL(inter_module_put);
+
+MODULE_LICENSE("GPL");
+
diff --git a/kernel/module.c b/kernel/module.c
index e058aed..5aad477 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1670,6 +1670,9 @@
 		goto free_mod;
 	}
 
+	/* Userspace could have altered the string after the strlen_user() */
+	args[arglen - 1] = '\0';
+
 	if (find_module(mod->name)) {
 		err = -EEXIST;
 		goto free_mod;
diff --git a/kernel/power/console.c b/kernel/power/console.c
index 579d239..623786d 100644
--- a/kernel/power/console.c
+++ b/kernel/power/console.c
@@ -9,7 +9,9 @@
 #include <linux/console.h>
 #include "power.h"
 
-#ifdef SUSPEND_CONSOLE
+#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+#define SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1)
+
 static int orig_fgconsole, orig_kmsg;
 
 int pm_prepare_console(void)
diff --git a/kernel/power/power.h b/kernel/power/power.h
index d8f0d1a..388dba6 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -1,14 +1,6 @@
 #include <linux/suspend.h>
 #include <linux/utsname.h>
 
-/* With SUSPEND_CONSOLE defined suspend looks *really* cool, but
-   we probably do not take enough locks for switching consoles, etc,
-   so bad things might happen.
-*/
-#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
-#define SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1)
-#endif
-
 struct swsusp_info {
 	struct new_utsname	uts;
 	u32			version_code;
@@ -42,14 +34,6 @@
 
 extern struct subsystem power_subsys;
 
-#ifdef SUSPEND_CONSOLE
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
-#else
-static int pm_prepare_console(void) { return 0; }
-static void pm_restore_console(void) {}
-#endif
-
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
 
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 59c91c1..4e90905 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -743,7 +743,6 @@
 	if (!bio)
 		return -ENOMEM;
 	bio->bi_sector = page_off * (PAGE_SIZE >> 9);
-	bio_get(bio);
 	bio->bi_bdev = resume_bdev;
 	bio->bi_end_io = end_io;
 
@@ -753,14 +752,13 @@
 		goto Done;
 	}
 
-	if (rw == WRITE)
-		bio_set_pages_dirty(bio);
 
 	atomic_set(&io_done, 1);
 	submit_bio(rw | (1 << BIO_RW_SYNC), bio);
 	while (atomic_read(&io_done))
 		yield();
-
+	if (rw == READ)
+		bio_set_pages_dirty(bio);
  Done:
 	bio_put(bio);
 	return error;
diff --git a/kernel/sched.c b/kernel/sched.c
index f77f23f..bc38804 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5551,13 +5551,15 @@
 			-1
 #endif
 		);
-	printk("migration_cost=");
-	for (distance = 0; distance <= max_distance; distance++) {
-		if (distance)
-			printk(",");
-		printk("%ld", (long)migration_cost[distance] / 1000);
+	if (system_state == SYSTEM_BOOTING) {
+		printk("migration_cost=");
+		for (distance = 0; distance <= max_distance; distance++) {
+			if (distance)
+				printk(",");
+			printk("%ld", (long)migration_cost[distance] / 1000);
+		}
+		printk("\n");
 	}
-	printk("\n");
 	j1 = jiffies;
 	if (migration_debug)
 		printk("migration: %ld seconds\n", (j1-j0)/HZ);
@@ -6109,7 +6111,7 @@
 	runqueue_t *rq;
 	int i, j, k;
 
-	for (i = 0; i < NR_CPUS; i++) {
+	for_each_cpu(i) {
 		prio_array_t *array;
 
 		rq = cpu_rq(i);
diff --git a/kernel/sys.c b/kernel/sys.c
index 0929c69..f91218a 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -428,7 +428,7 @@
 {
 #ifdef CONFIG_KEXEC
 	struct kimage *image;
-	image = xchg(&kexec_image, 0);
+	image = xchg(&kexec_image, NULL);
 	if (!image) {
 		return;
 	}
diff --git a/kernel/timer.c b/kernel/timer.c
index 4f1cb0a..b9dad39 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -495,7 +495,7 @@
 	base = &__get_cpu_var(tvec_bases);
 	spin_lock(&base->t_base.lock);
 	expires = base->timer_jiffies + (LONG_MAX >> 1);
-	list = 0;
+	list = NULL;
 
 	/* Look for timer events in tv1. */
 	j = base->timer_jiffies & TVR_MASK;
diff --git a/lib/kobject.c b/lib/kobject.c
index 7a0e680..efe67fa 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -72,6 +72,8 @@
 	 * Add 1 to strlen for leading '/' of each level.
 	 */
 	do {
+		if (kobject_name(parent) == NULL)
+			return 0;
 		length += strlen(kobject_name(parent)) + 1;
 		parent = parent->parent;
 	} while (parent);
@@ -107,6 +109,8 @@
 	int len;
 
 	len = get_kobj_path_length(kobj);
+	if (len == 0)
+		return NULL;
 	path = kmalloc(len, gfp_mask);
 	if (!path)
 		return NULL;
@@ -162,6 +166,11 @@
 		return -ENOENT;
 	if (!kobj->k_name)
 		kobj->k_name = kobj->name;
+	if (!kobj->k_name) {
+		pr_debug("kobject attempted to be registered with no name!\n");
+		WARN_ON(1);
+		return -EINVAL;
+	}
 	parent = kobject_get(kobj->parent);
 
 	pr_debug("kobject %s: registering. parent: %s, set: %s\n",
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index f56e27a..1b1985c 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -22,7 +22,7 @@
 #include <linux/kobject.h>
 #include <net/sock.h>
 
-#define BUFFER_SIZE	1024	/* buffer for the variables */
+#define BUFFER_SIZE	2048	/* buffer for the variables */
 #define NUM_ENVP	32	/* number of env pointers */
 
 #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index c8bb8cc..d8b6bb4 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -72,9 +72,9 @@
 
 	for (;;) {
 		for (i = 0; i < loops_per_jiffy * HZ; i++) {
-			cpu_relax();
 			if (__raw_spin_trylock(&lock->raw_lock))
 				return;
+			__delay(1);
 		}
 		/* lockup suspected: */
 		if (print_once) {
@@ -144,9 +144,9 @@
 
 	for (;;) {
 		for (i = 0; i < loops_per_jiffy * HZ; i++) {
-			cpu_relax();
 			if (__raw_read_trylock(&lock->raw_lock))
 				return;
+			__delay(1);
 		}
 		/* lockup suspected: */
 		if (print_once) {
@@ -217,9 +217,9 @@
 
 	for (;;) {
 		for (i = 0; i < loops_per_jiffy * HZ; i++) {
-			cpu_relax();
 			if (__raw_write_trylock(&lock->raw_lock))
 				return;
+			__delay(1);
 		}
 		/* lockup suspected: */
 		if (print_once) {
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index b21d78c..67f2951 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -107,7 +107,7 @@
 	set_page_count(page, 1);
 	page[1].mapping = (void *)free_huge_page;
 	for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
-		clear_highpage(&page[i]);
+		clear_user_highpage(&page[i], addr);
 	return page;
 }
 
@@ -391,12 +391,7 @@
 
 	if (!new_page) {
 		page_cache_release(old_page);
-
-		/* Logically this is OOM, not a SIGBUS, but an OOM
-		 * could cause the kernel to go killing other
-		 * processes which won't help the hugepage situation
-		 * at all (?) */
-		return VM_FAULT_SIGBUS;
+		return VM_FAULT_OOM;
 	}
 
 	spin_unlock(&mm->page_table_lock);
@@ -444,6 +439,7 @@
 		page = alloc_huge_page(vma, address);
 		if (!page) {
 			hugetlb_put_quota(mapping);
+			ret = VM_FAULT_OOM;
 			goto out;
 		}
 
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 27da6d5..3bd7fb7 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1159,6 +1159,7 @@
 		return interleave_nodes(pol);
 }
 
+#ifdef CONFIG_HUGETLBFS
 /* Return a zonelist suitable for a huge page allocation. */
 struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr)
 {
@@ -1172,6 +1173,7 @@
 	}
 	return zonelist_policy(GFP_HIGHUSER, pol);
 }
+#endif
 
 /* Allocate a page in interleaved policy.
    Own path because it needs to do special accounting. */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 44b4eb4..dde04ff 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1213,18 +1213,21 @@
 {
 	int cpu = 0;
 
-	memset(ret, 0, sizeof(*ret));
+	memset(ret, 0, nr * sizeof(unsigned long));
 	cpus_and(*cpumask, *cpumask, cpu_online_map);
 
 	cpu = first_cpu(*cpumask);
 	while (cpu < NR_CPUS) {
 		unsigned long *in, *out, off;
 
+		if (!cpu_isset(cpu, *cpumask))
+			continue;
+
 		in = (unsigned long *)&per_cpu(page_states, cpu);
 
 		cpu = next_cpu(cpu, *cpumask);
 
-		if (cpu < NR_CPUS)
+		if (likely(cpu < NR_CPUS))
 			prefetch(&per_cpu(page_states, cpu));
 
 		out = (unsigned long *)ret;
@@ -1886,8 +1889,7 @@
  * not check if the processor is online before following the pageset pointer.
  * Other parts of the kernel may not check if the zone is available.
  */
-static struct per_cpu_pageset
-	boot_pageset[NR_CPUS];
+static struct per_cpu_pageset boot_pageset[NR_CPUS];
 
 /*
  * Dynamically allocate memory for the
diff --git a/mm/slab.c b/mm/slab.c
index 7137025..d66c2b0 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -294,6 +294,7 @@
 	unsigned long next_reap;
 	int free_touched;
 	unsigned int free_limit;
+	unsigned int colour_next;	/* Per-node cache coloring */
 	spinlock_t list_lock;
 	struct array_cache *shared;	/* shared per node */
 	struct array_cache **alien;	/* on other nodes */
@@ -344,6 +345,7 @@
 	INIT_LIST_HEAD(&parent->slabs_free);
 	parent->shared = NULL;
 	parent->alien = NULL;
+	parent->colour_next = 0;
 	spin_lock_init(&parent->list_lock);
 	parent->free_objects = 0;
 	parent->free_touched = 0;
@@ -390,7 +392,6 @@
 
 	size_t colour;		/* cache colouring range */
 	unsigned int colour_off;	/* colour offset */
-	unsigned int colour_next;	/* cache colouring */
 	struct kmem_cache *slabp_cache;
 	unsigned int slab_size;
 	unsigned int dflags;	/* dynamic flags */
@@ -883,14 +884,14 @@
 	}
 }
 
-static void drain_alien_cache(struct kmem_cache *cachep, struct kmem_list3 *l3)
+static void drain_alien_cache(struct kmem_cache *cachep, struct array_cache **alien)
 {
 	int i = 0;
 	struct array_cache *ac;
 	unsigned long flags;
 
 	for_each_online_node(i) {
-		ac = l3->alien[i];
+		ac = alien[i];
 		if (ac) {
 			spin_lock_irqsave(&ac->lock, flags);
 			__drain_alien_cache(cachep, ac, i);
@@ -899,9 +900,18 @@
 	}
 }
 #else
-#define alloc_alien_cache(node, limit) do { } while (0)
-#define free_alien_cache(ac_ptr) do { } while (0)
-#define drain_alien_cache(cachep, l3) do { } while (0)
+
+#define drain_alien_cache(cachep, alien) do { } while (0)
+
+static inline struct array_cache **alloc_alien_cache(int node, int limit)
+{
+	return (struct array_cache **) 0x01020304ul;
+}
+
+static inline void free_alien_cache(struct array_cache **ac_ptr)
+{
+}
+
 #endif
 
 static int __devinit cpuup_callback(struct notifier_block *nfb,
@@ -935,6 +945,11 @@
 				l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
 				    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
+				/*
+				 * The l3s don't come and go as CPUs come and
+				 * go.  cache_chain_mutex is sufficient
+				 * protection here.
+				 */
 				cachep->nodelists[node] = l3;
 			}
 
@@ -949,26 +964,46 @@
 		   & array cache's */
 		list_for_each_entry(cachep, &cache_chain, next) {
 			struct array_cache *nc;
+			struct array_cache *shared;
+			struct array_cache **alien;
 
 			nc = alloc_arraycache(node, cachep->limit,
-					      cachep->batchcount);
+						cachep->batchcount);
 			if (!nc)
 				goto bad;
+			shared = alloc_arraycache(node,
+					cachep->shared * cachep->batchcount,
+					0xbaadf00d);
+			if (!shared)
+				goto bad;
+
+			alien = alloc_alien_cache(node, cachep->limit);
+			if (!alien)
+				goto bad;
 			cachep->array[cpu] = nc;
 
 			l3 = cachep->nodelists[node];
 			BUG_ON(!l3);
-			if (!l3->shared) {
-				if (!(nc = alloc_arraycache(node,
-							    cachep->shared *
-							    cachep->batchcount,
-							    0xbaadf00d)))
-					goto bad;
 
-				/* we are serialised from CPU_DEAD or
-				   CPU_UP_CANCELLED by the cpucontrol lock */
-				l3->shared = nc;
+			spin_lock_irq(&l3->list_lock);
+			if (!l3->shared) {
+				/*
+				 * We are serialised from CPU_DEAD or
+				 * CPU_UP_CANCELLED by the cpucontrol lock
+				 */
+				l3->shared = shared;
+				shared = NULL;
 			}
+#ifdef CONFIG_NUMA
+			if (!l3->alien) {
+				l3->alien = alien;
+				alien = NULL;
+			}
+#endif
+			spin_unlock_irq(&l3->list_lock);
+
+			kfree(shared);
+			free_alien_cache(alien);
 		}
 		mutex_unlock(&cache_chain_mutex);
 		break;
@@ -977,25 +1012,34 @@
 		break;
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_DEAD:
+		/*
+		 * Even if all the cpus of a node are down, we don't free the
+		 * kmem_list3 of any cache. This to avoid a race between
+		 * cpu_down, and a kmalloc allocation from another cpu for
+		 * memory from the node of the cpu going down.  The list3
+		 * structure is usually allocated from kmem_cache_create() and
+		 * gets destroyed at kmem_cache_destroy().
+		 */
 		/* fall thru */
 	case CPU_UP_CANCELED:
 		mutex_lock(&cache_chain_mutex);
 
 		list_for_each_entry(cachep, &cache_chain, next) {
 			struct array_cache *nc;
+			struct array_cache *shared;
+			struct array_cache **alien;
 			cpumask_t mask;
 
 			mask = node_to_cpumask(node);
-			spin_lock_irq(&cachep->spinlock);
 			/* cpu is dead; no one can alloc from it. */
 			nc = cachep->array[cpu];
 			cachep->array[cpu] = NULL;
 			l3 = cachep->nodelists[node];
 
 			if (!l3)
-				goto unlock_cache;
+				goto free_array_cache;
 
-			spin_lock(&l3->list_lock);
+			spin_lock_irq(&l3->list_lock);
 
 			/* Free limit for this kmem_list3 */
 			l3->free_limit -= cachep->batchcount;
@@ -1003,34 +1047,44 @@
 				free_block(cachep, nc->entry, nc->avail, node);
 
 			if (!cpus_empty(mask)) {
-				spin_unlock(&l3->list_lock);
-				goto unlock_cache;
+				spin_unlock_irq(&l3->list_lock);
+				goto free_array_cache;
 			}
 
-			if (l3->shared) {
+			shared = l3->shared;
+			if (shared) {
 				free_block(cachep, l3->shared->entry,
 					   l3->shared->avail, node);
-				kfree(l3->shared);
 				l3->shared = NULL;
 			}
-			if (l3->alien) {
-				drain_alien_cache(cachep, l3);
-				free_alien_cache(l3->alien);
-				l3->alien = NULL;
-			}
 
-			/* free slabs belonging to this node */
-			if (__node_shrink(cachep, node)) {
-				cachep->nodelists[node] = NULL;
-				spin_unlock(&l3->list_lock);
-				kfree(l3);
-			} else {
-				spin_unlock(&l3->list_lock);
+			alien = l3->alien;
+			l3->alien = NULL;
+
+			spin_unlock_irq(&l3->list_lock);
+
+			kfree(shared);
+			if (alien) {
+				drain_alien_cache(cachep, alien);
+				free_alien_cache(alien);
 			}
-		      unlock_cache:
-			spin_unlock_irq(&cachep->spinlock);
+free_array_cache:
 			kfree(nc);
 		}
+		/*
+		 * In the previous loop, all the objects were freed to
+		 * the respective cache's slabs,  now we can go ahead and
+		 * shrink each nodelist to its limit.
+		 */
+		list_for_each_entry(cachep, &cache_chain, next) {
+			l3 = cachep->nodelists[node];
+			if (!l3)
+				continue;
+			spin_lock_irq(&l3->list_lock);
+			/* free slabs belonging to this node */
+			__node_shrink(cachep, node);
+			spin_unlock_irq(&l3->list_lock);
+		}
 		mutex_unlock(&cache_chain_mutex);
 		break;
 #endif
@@ -1119,7 +1173,6 @@
 		BUG();
 
 	cache_cache.colour = left_over / cache_cache.colour_off;
-	cache_cache.colour_next = 0;
 	cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) +
 				      sizeof(struct slab), cache_line_size());
 
@@ -2011,18 +2064,16 @@
 
 	smp_call_function_all_cpus(do_drain, cachep);
 	check_irq_on();
-	spin_lock_irq(&cachep->spinlock);
 	for_each_online_node(node) {
 		l3 = cachep->nodelists[node];
 		if (l3) {
-			spin_lock(&l3->list_lock);
+			spin_lock_irq(&l3->list_lock);
 			drain_array_locked(cachep, l3->shared, 1, node);
-			spin_unlock(&l3->list_lock);
+			spin_unlock_irq(&l3->list_lock);
 			if (l3->alien)
-				drain_alien_cache(cachep, l3);
+				drain_alien_cache(cachep, l3->alien);
 		}
 	}
-	spin_unlock_irq(&cachep->spinlock);
 }
 
 static int __node_shrink(struct kmem_cache *cachep, int node)
@@ -2324,20 +2375,20 @@
 		 */
 		ctor_flags |= SLAB_CTOR_ATOMIC;
 
-	/* About to mess with non-constant members - lock. */
+	/* Take the l3 list lock to change the colour_next on this node */
 	check_irq_off();
-	spin_lock(&cachep->spinlock);
+	l3 = cachep->nodelists[nodeid];
+	spin_lock(&l3->list_lock);
 
 	/* Get colour for the slab, and cal the next value. */
-	offset = cachep->colour_next;
-	cachep->colour_next++;
-	if (cachep->colour_next >= cachep->colour)
-		cachep->colour_next = 0;
+	offset = l3->colour_next;
+	l3->colour_next++;
+	if (l3->colour_next >= cachep->colour)
+		l3->colour_next = 0;
+	spin_unlock(&l3->list_lock);
+
 	offset *= cachep->colour_off;
 
-	spin_unlock(&cachep->spinlock);
-
-	check_irq_off();
 	if (local_flags & __GFP_WAIT)
 		local_irq_enable();
 
@@ -2367,7 +2418,6 @@
 	if (local_flags & __GFP_WAIT)
 		local_irq_disable();
 	check_irq_off();
-	l3 = cachep->nodelists[nodeid];
 	spin_lock(&l3->list_lock);
 
 	/* Make slab active. */
@@ -2725,6 +2775,7 @@
 	BUG_ON(!l3);
 
       retry:
+	check_irq_off();
 	spin_lock(&l3->list_lock);
 	entry = l3->slabs_partial.next;
 	if (entry == &l3->slabs_partial) {
@@ -3304,11 +3355,11 @@
 	smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
 
 	check_irq_on();
-	spin_lock_irq(&cachep->spinlock);
+	spin_lock(&cachep->spinlock);
 	cachep->batchcount = batchcount;
 	cachep->limit = limit;
 	cachep->shared = shared;
-	spin_unlock_irq(&cachep->spinlock);
+	spin_unlock(&cachep->spinlock);
 
 	for_each_online_cpu(i) {
 		struct array_cache *ccold = new.new[i];
@@ -3440,7 +3491,7 @@
 
 		l3 = searchp->nodelists[numa_node_id()];
 		if (l3->alien)
-			drain_alien_cache(searchp, l3);
+			drain_alien_cache(searchp, l3->alien);
 		spin_lock_irq(&l3->list_lock);
 
 		drain_array_locked(searchp, cpu_cache_get(searchp), 0,
@@ -3564,8 +3615,7 @@
 	int node;
 	struct kmem_list3 *l3;
 
-	check_irq_on();
-	spin_lock_irq(&cachep->spinlock);
+	spin_lock(&cachep->spinlock);
 	active_objs = 0;
 	num_slabs = 0;
 	for_each_online_node(node) {
@@ -3573,7 +3623,8 @@
 		if (!l3)
 			continue;
 
-		spin_lock(&l3->list_lock);
+		check_irq_on();
+		spin_lock_irq(&l3->list_lock);
 
 		list_for_each(q, &l3->slabs_full) {
 			slabp = list_entry(q, struct slab, list);
@@ -3598,9 +3649,10 @@
 			num_slabs++;
 		}
 		free_objects += l3->free_objects;
-		shared_avail += l3->shared->avail;
+		if (l3->shared)
+			shared_avail += l3->shared->avail;
 
-		spin_unlock(&l3->list_lock);
+		spin_unlock_irq(&l3->list_lock);
 	}
 	num_slabs += active_slabs;
 	num_objs = num_slabs * cachep->num;
@@ -3644,7 +3696,7 @@
 	}
 #endif
 	seq_putc(m, '\n');
-	spin_unlock_irq(&cachep->spinlock);
+	spin_unlock(&cachep->spinlock);
 	return 0;
 }
 
diff --git a/mm/slob.c b/mm/slob.c
index 1c240c4..a1f42bd 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -336,7 +336,7 @@
 
 #ifdef CONFIG_SMP
 
-void *__alloc_percpu(size_t size, size_t align)
+void *__alloc_percpu(size_t size)
 {
 	int i;
 	struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);
diff --git a/mm/swap.c b/mm/swap.c
index bc2442a7..7624742 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -34,19 +34,22 @@
 /* How many pages do we try to swap or page in/out together? */
 int page_cluster;
 
+static void put_compound_page(struct page *page)
+{
+	page = (struct page *)page_private(page);
+	if (put_page_testzero(page)) {
+		void (*dtor)(struct page *page);
+
+		dtor = (void (*)(struct page *))page[1].mapping;
+		(*dtor)(page);
+	}
+}
+
 void put_page(struct page *page)
 {
-	if (unlikely(PageCompound(page))) {
-		page = (struct page *)page_private(page);
-		if (put_page_testzero(page)) {
-			void (*dtor)(struct page *page);
-
-			dtor = (void (*)(struct page *))page[1].mapping;
-			(*dtor)(page);
-		}
-		return;
-	}
-	if (put_page_testzero(page))
+	if (unlikely(PageCompound(page)))
+		put_compound_page(page);
+	else if (put_page_testzero(page))
 		__page_cache_release(page);
 }
 EXPORT_SYMBOL(put_page);
@@ -244,6 +247,15 @@
 		struct page *page = pages[i];
 		struct zone *pagezone;
 
+		if (unlikely(PageCompound(page))) {
+			if (zone) {
+				spin_unlock_irq(&zone->lru_lock);
+				zone = NULL;
+			}
+			put_compound_page(page);
+			continue;
+		}
+
 		if (!put_page_testzero(page))
 			continue;
 
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index ce617b3..802baf7 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -46,7 +46,7 @@
 #define PRINTR(format, args...) do { if (net_ratelimit()) \
                                 printk(format , ## args); } while (0)
 
-static unsigned int nlbufsiz = 4096;
+static unsigned int nlbufsiz = NLMSG_GOODSIZE;
 module_param(nlbufsiz, uint, 0600);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
                            "(defaults to 4096)");
@@ -98,12 +98,14 @@
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
 {
 	struct sk_buff *skb;
+	unsigned int n;
 
-	skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
+	n = max(size, nlbufsiz);
+	skb = alloc_skb(n, GFP_ATOMIC);
 	if (!skb) {
 		PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer "
-		       "of size %ub!\n", nlbufsiz);
-		if (size < nlbufsiz) {
+		       "of size %ub!\n", n);
+		if (n > size) {
 			/* try to allocate only as much as we need for
 			 * current packet */
 			skb = alloc_skb(size, GFP_ATOMIC);
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 00729b3..cbd4020 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -934,6 +934,13 @@
 		BUGPRINT("Entries_size never zero\n");
 		return -EINVAL;
 	}
+	/* overflow check */
+	if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
+		return -ENOMEM;
+
 	countersize = COUNTER_OFFSET(tmp.nentries) * 
 					(highest_possible_processor_id()+1);
 	newinfo = (struct ebt_table_info *)
diff --git a/net/core/dev.c b/net/core/dev.c
index ffb8207..2afb0de 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3237,7 +3237,7 @@
 	 *	Initialise the packet receive queues.
 	 */
 
-	for (i = 0; i < NR_CPUS; i++) {
+	for_each_cpu(i) {
 		struct softnet_data *queue;
 
 		queue = &per_cpu(softnet_data, i);
diff --git a/net/core/utils.c b/net/core/utils.c
index ac1d1fc..fdc4f38 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -121,7 +121,7 @@
 {
 	int i;
 
-	for (i = 0; i < NR_CPUS; i++) {
+	for_each_cpu(i) {
 		struct nrnd_state *state = &per_cpu(net_rand_state,i);
 		__net_srandom(state, i+jiffies);
 	}
@@ -133,7 +133,7 @@
 	unsigned long seed[NR_CPUS];
 
 	get_random_bytes(seed, sizeof(seed));
-	for (i = 0; i < NR_CPUS; i++) {
+	for_each_cpu(i) {
 		struct nrnd_state *state = &per_cpu(net_rand_state,i);
 		__net_srandom(state, seed[i]);
 	}
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index d2b5933..add3cae 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -15,7 +15,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
 
-#include <asm/bug.h>
 #include <asm/div64.h>
 
 #include "tfrc.h"
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 6bc0887..4d1c409 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -524,7 +524,7 @@
 					  iph->tos;
 
 	if (ip_options_echo(&icmp_param.replyopts, skb_in))
-		goto ende;
+		goto out_unlock;
 
 
 	/*
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 0b4e95f..64ce52b 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1578,7 +1578,7 @@
 			new_in = psf->sf_count[MCAST_INCLUDE] != 0;
 		if (new_in) {
 			if (!psf->sf_oldin) {
-				struct ip_sf_list *prev = 0;
+				struct ip_sf_list *prev = NULL;
 
 				for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) {
 					if (dpsf->sf_inaddr == psf->sf_inaddr)
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index afe3d8f..dd1048b 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -807,6 +807,13 @@
 	if (len != sizeof(tmp) + tmp.size)
 		return -ENOPROTOOPT;
 
+	/* overflow check */
+	if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES)
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+		return -ENOMEM;
+
 	newinfo = xt_alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index c9ebbe0..e0b5926 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -1216,7 +1216,7 @@
 
 	b = skb->tail;
 
-	type |= NFNL_SUBSYS_CTNETLINK << 8;
+	type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
 	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
 	nfmsg = NLMSG_DATA(nlh);
 
@@ -1567,6 +1567,7 @@
 };
 
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
 static int __init ctnetlink_init(void)
 {
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index d3c5a37..4ba4463 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -71,6 +71,7 @@
 
 		exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
 		exp->mask.src.ip = 0xffffffff;
+		exp->mask.src.u.udp.port = 0;
 		exp->mask.dst.ip = 0xffffffff;
 		exp->mask.dst.u.udp.port = 0xffff;
 		exp->mask.dst.protonum = 0xff;
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index ad438fb..92c5499 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -209,8 +209,8 @@
 	    && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
 		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
-		if (ct->tuplehash[dir].tuple.src.ip !=
-		    ct->tuplehash[!dir].tuple.dst.ip) {
+		if (ct->tuplehash[dir].tuple.dst.ip !=
+		    ct->tuplehash[!dir].tuple.src.ip) {
 			dst_release((*pskb)->dst);
 			(*pskb)->dst = NULL;
 		}
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 2371b20..16f47c6 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -921,6 +921,13 @@
 	if (len != sizeof(tmp) + tmp.size)
 		return -ENOPROTOOPT;
 
+	/* overflow check */
+	if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES)
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+		return -ENOMEM;
+
 	newinfo = xt_alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 641dbc4..180a9ea 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -35,6 +35,10 @@
  * each nlgroup you are using, so the total kernel memory usage increases
  * by that factor.
  *
+ * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since
+ * nlbufsiz is used with alloc_skb, which adds another
+ * sizeof(struct skb_shared_info).  Use NLMSG_GOODSIZE instead.
+ *
  * flushtimeout:
  *   Specify, after how many hundredths of a second the queue should be
  *   flushed even if it is not full yet.
@@ -76,7 +80,7 @@
 
 #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
 
-static unsigned int nlbufsiz = 4096;
+static unsigned int nlbufsiz = NLMSG_GOODSIZE;
 module_param(nlbufsiz, uint, 0400);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
 
@@ -143,22 +147,26 @@
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
 {
 	struct sk_buff *skb;
+	unsigned int n;
 
 	/* alloc skb which should be big enough for a whole
 	 * multipart message. WARNING: has to be <= 131000
 	 * due to slab allocator restrictions */
 
-	skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
+	n = max(size, nlbufsiz);
+	skb = alloc_skb(n, GFP_ATOMIC);
 	if (!skb) {
-		PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n",
-			nlbufsiz);
+		PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n);
 
-		/* try to allocate only as much as we need for 
-		 * current packet */
+		if (n > size) {
+			/* try to allocate only as much as we need for 
+			 * current packet */
 
-		skb = alloc_skb(size, GFP_ATOMIC);
-		if (!skb)
-			PRINTR("ipt_ULOG: can't even allocate %ub\n", size);
+			skb = alloc_skb(size, GFP_ATOMIC);
+			if (!skb)
+				PRINTR("ipt_ULOG: can't even allocate %ub\n",
+				       size);
+		}
 	}
 
 	return skb;
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c
index 18ca825..5a7a265 100644
--- a/net/ipv4/netfilter/ipt_policy.c
+++ b/net/ipv4/netfilter/ipt_policy.c
@@ -26,10 +26,13 @@
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
 {
-#define MATCH(x,y)	(!e->match.x || ((e->x == (y)) ^ e->invert.x))
+#define MATCH_ADDR(x,y,z)	(!e->match.x ||				     \
+		                 ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \
+				  ^ e->invert.x))
+#define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
 
-	return MATCH(saddr, x->props.saddr.a4 & e->smask) &&
-	       MATCH(daddr, x->id.daddr.a4 & e->dmask) &&
+	return MATCH_ADDR(saddr, smask, x->props.saddr.a4) &&
+	       MATCH_ADDR(daddr, dmask, x->id.daddr.a4) &&
 	       MATCH(proto, x->id.proto) &&
 	       MATCH(mode, x->props.mode) &&
 	       MATCH(spi, x->id.spi) &&
@@ -89,7 +92,7 @@
 			return 0;
 	}
 
-	return strict ? 1 : 0;
+	return strict ? i == info->len : 0;
 }
 
 static int match(const struct sk_buff *skb,
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 39d49dc..1b167c4b 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -49,7 +49,7 @@
 	int res = 0;
 	int cpu;
 
-	for (cpu = 0; cpu < NR_CPUS; cpu++)
+	for_each_cpu(cpu)
 		res += proto->stats[cpu].inuse;
 
 	return res;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 42196ba..45f7ae5 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -8,7 +8,6 @@
  * 	
  */
 
-#include <asm/bug.h>
 #include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/inetdevice.h>
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 4420948..807c021 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1978,7 +1978,7 @@
 			new_in = psf->sf_count[MCAST_INCLUDE] != 0;
 		if (new_in) {
 			if (!psf->sf_oldin) {
-				struct ip6_sf_list *prev = 0;
+				struct ip6_sf_list *prev = NULL;
 
 				for (dpsf=pmc->mca_tomb; dpsf;
 				     dpsf=dpsf->sf_next) {
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 847068f..74ff56c 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -978,6 +978,13 @@
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
 
+	/* overflow check */
+	if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES)
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+		return -ENOMEM;
+
 	newinfo = xt_alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c
index afe1cc4..3d39ec9 100644
--- a/net/ipv6/netfilter/ip6t_policy.c
+++ b/net/ipv6/netfilter/ip6t_policy.c
@@ -26,8 +26,9 @@
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
 {
-#define MATCH_ADDR(x,y,z)	(!e->match.x || \
-				 ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x)
+#define MATCH_ADDR(x,y,z)	(!e->match.x ||				       \
+				 ((!ip6_masked_addrcmp(&e->x.a6, &e->y.a6, z)) \
+				  ^ e->invert.x))
 #define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
 	
 	return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
@@ -91,7 +92,7 @@
 			return 0;
 	}
 
-	return strict ? 1 : 0;
+	return strict ? i == info->len : 0;
 }
 
 static int match(const struct sk_buff *skb,
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 50a13e7..4238b1e 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -38,7 +38,7 @@
 	int res = 0;
 	int cpu;
 
-	for (cpu=0; cpu<NR_CPUS; cpu++)
+	for_each_cpu(cpu)
 		res += proto->stats[cpu].inuse;
 
 	return res;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 66f1d12..738376c 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -35,7 +35,6 @@
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
-#include <asm/bug.h>
 
 #include <net/ip.h>
 #include <net/sock.h>
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 69bd957..91cce8b 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -11,7 +11,6 @@
  * 
  */
 
-#include <asm/bug.h>
 #include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/netdevice.h>
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 62bb509..0ce337a 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -188,7 +188,7 @@
 struct nf_conntrack_protocol *
 __nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
 {
-	if (unlikely(nf_ct_protos[l3proto] == NULL))
+	if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
 		return &nf_conntrack_generic_protocol;
 
 	return nf_ct_protos[l3proto][protocol];
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index ab0c920..6f210f3 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -657,8 +657,6 @@
 	/* FIXME should be configurable whether IPv4 and IPv6 FTP connections
 		 are tracked or not - YK */
 	for (i = 0; i < ports_c; i++) {
-		memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper));
-
 		ftp[i][0].tuple.src.l3num = PF_INET;
 		ftp[i][1].tuple.src.l3num = PF_INET6;
 		for (j = 0; j < 2; j++) {
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 73ab16b..9ff34630 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1232,7 +1232,7 @@
 
 	b = skb->tail;
 
-	type |= NFNL_SUBSYS_CTNETLINK << 8;
+	type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
 	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
 	nfmsg = NLMSG_DATA(nlh);
 
@@ -1589,6 +1589,7 @@
 };
 
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
 static int __init ctnetlink_init(void)
 {
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index e10512e..3b3c781 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -37,7 +37,7 @@
 #include "../bridge/br_private.h"
 #endif
 
-#define NFULNL_NLBUFSIZ_DEFAULT	4096
+#define NFULNL_NLBUFSIZ_DEFAULT	NLMSG_GOODSIZE
 #define NFULNL_TIMEOUT_DEFAULT 	100	/* every second */
 #define NFULNL_QTHRESH_DEFAULT 	100	/* 100 packets */
 
@@ -314,24 +314,28 @@
 					unsigned int pkt_size)
 {
 	struct sk_buff *skb;
+	unsigned int n;
 
 	UDEBUG("entered (%u, %u)\n", inst_size, pkt_size);
 
 	/* alloc skb which should be big enough for a whole multipart
 	 * message.  WARNING: has to be <= 128k due to slab restrictions */
 
-	skb = alloc_skb(inst_size, GFP_ATOMIC);
+	n = max(inst_size, pkt_size);
+	skb = alloc_skb(n, GFP_ATOMIC);
 	if (!skb) {
 		PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n",
 			inst_size);
 
-		/* try to allocate only as much as we need for current
-		 * packet */
+		if (n > pkt_size) {
+			/* try to allocate only as much as we need for current
+			 * packet */
 
-		skb = alloc_skb(pkt_size, GFP_ATOMIC);
-		if (!skb)
-			PRINTR("nfnetlink_log: can't even alloc %u bytes\n",
-				pkt_size);
+			skb = alloc_skb(pkt_size, GFP_ATOMIC);
+			if (!skb)
+				PRINTR("nfnetlink_log: can't even alloc %u "
+				       "bytes\n", pkt_size);
+		}
 	}
 
 	return skb;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 18ed9c5..cac38b2e 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -825,7 +825,8 @@
 	}
 
 	if (nfqa[NFQA_MARK-1])
-		skb->nfmark = ntohl(*(u_int32_t *)NFA_DATA(nfqa[NFQA_MARK-1]));
+		entry->skb->nfmark = ntohl(*(u_int32_t *)
+		                           NFA_DATA(nfqa[NFQA_MARK-1]));
 		
 	issue_verdict(entry, verdict);
 	instance_put(queue);
diff --git a/net/socket.c b/net/socket.c
index b38a263..a00851f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2078,7 +2078,7 @@
 	int cpu;
 	int counter = 0;
 
-	for (cpu = 0; cpu < NR_CPUS; cpu++)
+	for_each_cpu(cpu)
 		counter += per_cpu(sockets_in_use, cpu);
 
 	/* It can be negative, by the way. 8) */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 077bbf9..dbf4620 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -13,7 +13,6 @@
  *
  */
 
-#include <asm/bug.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5760e05..d64aae8 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -123,7 +123,17 @@
      then echo yes ; \
      else echo no ; fi)
 ifeq ($(KBUILD_HAVE_NLS),no)
-HOSTCFLAGS	+= -DKBUILD_NO_NLS
+  HOSTCFLAGS   += -DKBUILD_NO_NLS
+else
+  KBUILD_NEED_LINTL := $(shell \
+    if echo -e "\#include <libintl.h>\nint main(int a, char** b) { gettext(\"\"); return 0; }\n" | \
+      $(HOSTCC) $(HOSTCFLAGS) -x c - -o /dev/null> /dev/null 2>&1 ; \
+    then echo no ; \
+    else echo yes ; fi)
+  ifeq ($(KBUILD_NEED_LINTL),yes)
+    HOSTLOADLIBES_conf += -lintl
+    HOSTLOADLIBES_mconf        += -lintl
+  endif
 endif
 
 # generated files seem to need this to find local include files
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
index fae3e29..bbf4887 100644
--- a/scripts/kconfig/lxdialog/Makefile
+++ b/scripts/kconfig/lxdialog/Makefile
@@ -2,8 +2,11 @@
 #
 
 check-lxdialog  := $(srctree)/$(src)/check-lxdialog.sh
-HOST_EXTRACFLAGS:= $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
-HOST_LOADLIBES  := $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
+
+# Use reursively expanded variables so we do not call gcc unless
+# we really need to do so. (Do not call gcc as part of make mrproper)
+HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
+HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
  
 HOST_EXTRACFLAGS += -DLOCALE 
 
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index 448e353..120d624 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -4,17 +4,17 @@
 # What library to link
 ldflags()
 {
-	echo "main() {}" | $cc -lncursesw -xc - -o /dev/null 2> /dev/null
+	$cc -print-file-name=libncursesw.so | grep -q /
 	if [ $? -eq 0 ]; then
 		echo '-lncursesw'
 		exit
 	fi
-	echo "main() {}" | $cc -lncurses -xc - -o /dev/null 2> /dev/null
+	$cc -print-file-name=libncurses.so | grep -q /
 	if [ $? -eq 0 ]; then
 		echo '-lncurses'
 		exit
 	fi
-	echo "main() {}" | $cc -lcurses -xc - -o /dev/null 2> /dev/null
+	$cc -print-file-name=libcurses.so | grep -q /
 	if [ $? -eq 0 ]; then
 		echo '-lcurses'
 		exit
@@ -36,10 +36,13 @@
 	fi
 }
 
-compiler=""
+# Temp file, try to clean up after us
+tmp=.lxdialog.tmp
+trap "rm -f $tmp" 0 1 2 3 15
+
 # Check if we can link to ncurses
 check() {
-	echo "main() {}" | $cc -xc - -o /dev/null 2> /dev/null
+	echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null
 	if [ $? != 0 ]; then
 		echo " *** Unable to find the ncurses libraries."          1>&2
 		echo " *** make menuconfig require the ncurses libraries"  1>&2
@@ -59,6 +62,7 @@
 	exit 1
 fi
 
+cc=""
 case "$1" in
 	"-check")
 		shift
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index b59582b..f636f53 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -1,6 +1,6 @@
 config SECURITY_SELINUX
 	bool "NSA SELinux Support"
-	depends on SECURITY && NET && INET
+	depends on SECURITY_NETWORK && AUDIT && NET && INET
 	default n
 	help
 	  This selects NSA Security-Enhanced Linux (SELinux).
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 06d54d9..688c0a2 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -4,9 +4,7 @@
 
 obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/
 
-selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o
-
-selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
+selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o
 
 selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
 
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 53d6c7b..ac5d69b 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -43,13 +43,11 @@
 #undef S_
 };
 
-#ifdef CONFIG_AUDIT
 static const char *class_to_string[] = {
 #define S_(s) s,
 #include "class_to_string.h"
 #undef S_
 };
-#endif
 
 #define TB_(s) static const char * s [] = {
 #define TE_(s) };
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4ae834d..b7773bf 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -232,7 +232,6 @@
 	kfree(sbsec);
 }
 
-#ifdef CONFIG_SECURITY_NETWORK
 static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 {
 	struct sk_security_struct *ssec;
@@ -261,7 +260,6 @@
 	sk->sk_security = NULL;
 	kfree(ssec);
 }
-#endif	/* CONFIG_SECURITY_NETWORK */
 
 /* The security server must be initialized before
    any labeling or access decisions can be provided. */
@@ -2736,8 +2734,6 @@
 	return;
 }
 
-#ifdef CONFIG_SECURITY_NETWORK
-
 /* Returns error only if unable to parse addresses */
 static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad)
 {
@@ -3556,15 +3552,6 @@
 
 #endif	/* CONFIG_NETFILTER */
 
-#else
-
-static inline int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
-{
-	return 0;
-}
-
-#endif	/* CONFIG_SECURITY_NETWORK */
-
 static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
 	struct task_security_struct *tsec;
@@ -4340,7 +4327,6 @@
 	.getprocattr =                  selinux_getprocattr,
 	.setprocattr =                  selinux_setprocattr,
 
-#ifdef CONFIG_SECURITY_NETWORK
         .unix_stream_connect =		selinux_socket_unix_stream_connect,
 	.unix_may_send =		selinux_socket_unix_may_send,
 
@@ -4362,7 +4348,6 @@
 	.sk_alloc_security =		selinux_sk_alloc_security,
 	.sk_free_security =		selinux_sk_free_security,
 	.sk_getsid = 			selinux_sk_getsid_security,
-#endif
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	.xfrm_policy_alloc_security =	selinux_xfrm_policy_alloc,
@@ -4440,7 +4425,7 @@
    all processes and objects when they are created. */
 security_initcall(selinux_init);
 
-#if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_NETFILTER)
+#if defined(CONFIG_NETFILTER)
 
 static struct nf_hook_ops selinux_ipv4_op = {
 	.hook =		selinux_ipv4_postroute_last,
@@ -4501,13 +4486,13 @@
 }
 #endif
 
-#else /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */
+#else /* CONFIG_NETFILTER */
 
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 #define selinux_nf_ip_exit()
 #endif
 
-#endif /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */
+#endif /* CONFIG_NETFILTER */
 
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 int selinux_disable(void)
diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h
index 3a6d486..0741c28 100644
--- a/sound/oss/dmasound/tas_common.h
+++ b/sound/oss/dmasound/tas_common.h
@@ -178,10 +178,10 @@
 	if (write_mode & WRITE_SHADOW)
 		memcpy(self->shadow[reg_num],data,reg_width);
 	if (write_mode & WRITE_HW) {
-		rc=i2c_smbus_write_block_data(self->client,
-					      reg_num,
-					      reg_width,
-					      data);
+		rc=i2c_smbus_write_i2c_block_data(self->client,
+						  reg_num,
+						  reg_width,
+						  data);
 		if (rc < 0) {
 			printk("tas: I2C block write failed \n");  
 			return rc; 
@@ -199,10 +199,10 @@
 
 	if (reg_width==0 || self==NULL)
 		return -EINVAL;
-	rc=i2c_smbus_write_block_data(self->client,
-				      reg_num,
-				      reg_width,
-				      self->shadow[reg_num]);
+	rc=i2c_smbus_write_i2c_block_data(self->client,
+					  reg_num,
+					  reg_width,
+					  self->shadow[reg_num]);
 	if (rc < 0) {
 		printk("tas: I2C block write failed \n");
 		return rc;
diff --git a/sound/oss/emu10k1/recmgr.c b/sound/oss/emu10k1/recmgr.c
index 67c3fd0..2ce5618 100644
--- a/sound/oss/emu10k1/recmgr.c
+++ b/sound/oss/emu10k1/recmgr.c
@@ -29,7 +29,7 @@
  **********************************************************************
  */
 
-#include <asm/delay.h>
+#include <linux/delay.h>
 #include "8010.h"
 #include "recmgr.h"
 
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 4988f87..aa57170 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -66,7 +66,7 @@
 
 static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec)
 {
-	if (rec) {
+	if (rec->space) {
 		unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
 
 		dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
@@ -881,6 +881,7 @@
 	chip->can_capture = 1;
 	chip->num_freqs = ARRAY_SIZE(awacs_freqs);
 	chip->freq_table = awacs_freqs;
+	chip->pdev = NULL;
 
 	chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
 
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 15c63cb..838fc11 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -239,8 +239,8 @@
 	block[4] = (right_vol >> 8)  & 0xff;
 	block[5] = (right_vol >> 0)  & 0xff;
   
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL,
-				       6, block) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6,
+					   block) < 0) {
 		snd_printk("failed to set volume \n");
 		return -EINVAL;
 	}
@@ -345,8 +345,8 @@
 		val[1] = 0;
 	}
 
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-				       2, val) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+					   2, val) < 0) {
 		snd_printk("failed to set DRC\n");
 		return -EINVAL;
 	}
@@ -381,8 +381,8 @@
 	val[4] = 0x60;
 	val[5] = 0xa0;
 
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-				       6, val) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+					   6, val) < 0) {
 		snd_printk("failed to set DRC\n");
 		return -EINVAL;
 	}
@@ -492,8 +492,8 @@
 	vol = info->table[vol];
 	for (i = 0; i < info->bytes; i++)
 		block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
-	if (i2c_smbus_write_block_data(mix->i2c.client, info->reg,
-				       info->bytes, block) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg,
+					   info->bytes, block) < 0) {
 		snd_printk("failed to set mono volume %d\n", info->index);
 		return -EINVAL;
 	}
@@ -625,7 +625,8 @@
 		for (j = 0; j < 3; j++)
 			block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
 	}
-	if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg,
+					   9, block) < 0) {
 		snd_printk("failed to set mono volume %d\n", reg);
 		return -EINVAL;
 	}